mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-17 14:11:53 -06:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
866a06f5a0 | ||
|
|
da28077952 | ||
|
|
b5dc853b24 | ||
|
|
2efa10565a | ||
|
|
603abd5528 | ||
|
|
232ce79574 | ||
|
|
1eddf527ca | ||
|
|
bec3b479dc |
12
C/7z.h
12
C/7z.h
@@ -1,5 +1,5 @@
|
|||||||
/* 7z.h -- 7z interface
|
/* 7z.h -- 7z interface
|
||||||
2015-11-18 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_H
|
#ifndef __7Z_H
|
||||||
#define __7Z_H
|
#define __7Z_H
|
||||||
@@ -98,7 +98,7 @@ UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
|
|||||||
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
|
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
|
||||||
ILookInStream *stream, UInt64 startPos,
|
ILookInStream *stream, UInt64 startPos,
|
||||||
Byte *outBuffer, size_t outSize,
|
Byte *outBuffer, size_t outSize,
|
||||||
ISzAlloc *allocMain);
|
ISzAllocPtr allocMain);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -131,7 +131,7 @@ typedef struct
|
|||||||
#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i])
|
#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i])
|
||||||
|
|
||||||
void SzArEx_Init(CSzArEx *p);
|
void SzArEx_Init(CSzArEx *p);
|
||||||
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
|
void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc);
|
||||||
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
|
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
|
||||||
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
|
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
|
||||||
|
|
||||||
@@ -179,8 +179,8 @@ SRes SzArEx_Extract(
|
|||||||
size_t *outBufferSize, /* buffer size for output buffer */
|
size_t *outBufferSize, /* buffer size for output buffer */
|
||||||
size_t *offset, /* offset of stream for required file in *outBuffer */
|
size_t *offset, /* offset of stream for required file in *outBuffer */
|
||||||
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
||||||
ISzAlloc *allocMain,
|
ISzAllocPtr allocMain,
|
||||||
ISzAlloc *allocTemp);
|
ISzAllocPtr allocTemp);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -195,7 +195,7 @@ SZ_ERROR_FAIL
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
|
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
|
||||||
ISzAlloc *allocMain, ISzAlloc *allocTemp);
|
ISzAllocPtr allocMain, ISzAllocPtr allocTemp);
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
|
|||||||
12
C/7zAlloc.c
12
C/7zAlloc.c
@@ -1,8 +1,10 @@
|
|||||||
/* 7zAlloc.c -- Allocation functions
|
/* 7zAlloc.c -- Allocation functions
|
||||||
2015-11-09 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "7zAlloc.h"
|
#include "7zAlloc.h"
|
||||||
|
|
||||||
/* #define _SZ_ALLOC_DEBUG */
|
/* #define _SZ_ALLOC_DEBUG */
|
||||||
@@ -20,7 +22,7 @@ int g_allocCountTemp = 0;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *SzAlloc(void *p, size_t size)
|
void *SzAlloc(ISzAllocPtr p, size_t size)
|
||||||
{
|
{
|
||||||
UNUSED_VAR(p);
|
UNUSED_VAR(p);
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
@@ -32,7 +34,7 @@ void *SzAlloc(void *p, size_t size)
|
|||||||
return malloc(size);
|
return malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SzFree(void *p, void *address)
|
void SzFree(ISzAllocPtr p, void *address)
|
||||||
{
|
{
|
||||||
UNUSED_VAR(p);
|
UNUSED_VAR(p);
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
@@ -45,7 +47,7 @@ void SzFree(void *p, void *address)
|
|||||||
free(address);
|
free(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *SzAllocTemp(void *p, size_t size)
|
void *SzAllocTemp(ISzAllocPtr p, size_t size)
|
||||||
{
|
{
|
||||||
UNUSED_VAR(p);
|
UNUSED_VAR(p);
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
@@ -60,7 +62,7 @@ void *SzAllocTemp(void *p, size_t size)
|
|||||||
return malloc(size);
|
return malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SzFreeTemp(void *p, void *address)
|
void SzFreeTemp(ISzAllocPtr p, void *address)
|
||||||
{
|
{
|
||||||
UNUSED_VAR(p);
|
UNUSED_VAR(p);
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
|
|||||||
20
C/7zAlloc.h
20
C/7zAlloc.h
@@ -1,23 +1,19 @@
|
|||||||
/* 7zAlloc.h -- Allocation functions
|
/* 7zAlloc.h -- Allocation functions
|
||||||
2013-03-25 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_ALLOC_H
|
#ifndef __7Z_ALLOC_H
|
||||||
#define __7Z_ALLOC_H
|
#define __7Z_ALLOC_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include "7zTypes.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_BEGIN
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *SzAlloc(void *p, size_t size);
|
void *SzAlloc(ISzAllocPtr p, size_t size);
|
||||||
void SzFree(void *p, void *address);
|
void SzFree(ISzAllocPtr p, void *address);
|
||||||
|
|
||||||
void *SzAllocTemp(void *p, size_t size);
|
void *SzAllocTemp(ISzAllocPtr p, size_t size);
|
||||||
void SzFreeTemp(void *p, void *address);
|
void SzFreeTemp(ISzAllocPtr p, void *address);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_END
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
121
C/7zArcIn.c
121
C/7zArcIn.c
@@ -1,5 +1,5 @@
|
|||||||
/* 7zArcIn.c -- 7z Input functions
|
/* 7zArcIn.c -- 7z Input functions
|
||||||
2016-03-31 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
|
||||||
#define MY_ALLOC(T, p, size, alloc) { \
|
#define MY_ALLOC(T, p, size, alloc) { \
|
||||||
if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; }
|
if ((p = (T *)ISzAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; }
|
||||||
|
|
||||||
#define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) }
|
#define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) }
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
|||||||
|
|
||||||
#define SzBitUi32s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
|
#define SzBitUi32s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
|
||||||
|
|
||||||
static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
|
static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
if (num == 0)
|
if (num == 0)
|
||||||
{
|
{
|
||||||
@@ -75,18 +75,18 @@ static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SzBitUi32s_Free(CSzBitUi32s *p, ISzAlloc *alloc)
|
void SzBitUi32s_Free(CSzBitUi32s *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
IAlloc_Free(alloc, p->Defs); p->Defs = NULL;
|
ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL;
|
||||||
IAlloc_Free(alloc, p->Vals); p->Vals = NULL;
|
ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SzBitUi64s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
|
#define SzBitUi64s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
|
||||||
|
|
||||||
void SzBitUi64s_Free(CSzBitUi64s *p, ISzAlloc *alloc)
|
void SzBitUi64s_Free(CSzBitUi64s *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
IAlloc_Free(alloc, p->Defs); p->Defs = NULL;
|
ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL;
|
||||||
IAlloc_Free(alloc, p->Vals); p->Vals = NULL;
|
ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -107,18 +107,18 @@ static void SzAr_Init(CSzAr *p)
|
|||||||
p->CodersData = NULL;
|
p->CodersData = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
|
static void SzAr_Free(CSzAr *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
IAlloc_Free(alloc, p->PackPositions);
|
ISzAlloc_Free(alloc, p->PackPositions);
|
||||||
SzBitUi32s_Free(&p->FolderCRCs, alloc);
|
SzBitUi32s_Free(&p->FolderCRCs, alloc);
|
||||||
|
|
||||||
IAlloc_Free(alloc, p->FoCodersOffsets);
|
ISzAlloc_Free(alloc, p->FoCodersOffsets);
|
||||||
IAlloc_Free(alloc, p->FoStartPackStreamIndex);
|
ISzAlloc_Free(alloc, p->FoStartPackStreamIndex);
|
||||||
IAlloc_Free(alloc, p->FoToCoderUnpackSizes);
|
ISzAlloc_Free(alloc, p->FoToCoderUnpackSizes);
|
||||||
IAlloc_Free(alloc, p->FoToMainUnpackSizeIndex);
|
ISzAlloc_Free(alloc, p->FoToMainUnpackSizeIndex);
|
||||||
IAlloc_Free(alloc, p->CoderUnpackSizes);
|
ISzAlloc_Free(alloc, p->CoderUnpackSizes);
|
||||||
|
|
||||||
IAlloc_Free(alloc, p->CodersData);
|
ISzAlloc_Free(alloc, p->CodersData);
|
||||||
|
|
||||||
SzAr_Init(p);
|
SzAr_Init(p);
|
||||||
}
|
}
|
||||||
@@ -147,16 +147,16 @@ void SzArEx_Init(CSzArEx *p)
|
|||||||
SzBitUi64s_Init(&p->CTime);
|
SzBitUi64s_Init(&p->CTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
|
void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
IAlloc_Free(alloc, p->UnpackPositions);
|
ISzAlloc_Free(alloc, p->UnpackPositions);
|
||||||
IAlloc_Free(alloc, p->IsDirs);
|
ISzAlloc_Free(alloc, p->IsDirs);
|
||||||
|
|
||||||
IAlloc_Free(alloc, p->FolderToFile);
|
ISzAlloc_Free(alloc, p->FolderToFile);
|
||||||
IAlloc_Free(alloc, p->FileToFolder);
|
ISzAlloc_Free(alloc, p->FileToFolder);
|
||||||
|
|
||||||
IAlloc_Free(alloc, p->FileNameOffsets);
|
ISzAlloc_Free(alloc, p->FileNameOffsets);
|
||||||
IAlloc_Free(alloc, p->FileNames);
|
ISzAlloc_Free(alloc, p->FileNames);
|
||||||
|
|
||||||
SzBitUi32s_Free(&p->CRCs, alloc);
|
SzBitUi32s_Free(&p->CRCs, alloc);
|
||||||
SzBitUi32s_Free(&p->Attribs, alloc);
|
SzBitUi32s_Free(&p->Attribs, alloc);
|
||||||
@@ -305,7 +305,7 @@ static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems)
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAlloc *alloc)
|
static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
Byte allAreDefined;
|
Byte allAreDefined;
|
||||||
Byte *v2;
|
Byte *v2;
|
||||||
@@ -328,12 +328,12 @@ static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, I
|
|||||||
{
|
{
|
||||||
unsigned numBits = (unsigned)numItems & 7;
|
unsigned numBits = (unsigned)numItems & 7;
|
||||||
if (numBits != 0)
|
if (numBits != 0)
|
||||||
v2[numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits));
|
v2[(size_t)numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits));
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc)
|
static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
CSzData sd;
|
CSzData sd;
|
||||||
@@ -354,7 +354,7 @@ static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *c
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc)
|
static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
SzBitUi32s_Free(crcs, alloc);
|
SzBitUi32s_Free(crcs, alloc);
|
||||||
RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc));
|
RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc));
|
||||||
@@ -380,7 +380,7 @@ static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems)
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAlloc *alloc)
|
static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
RINOK(SzReadNumber32(sd, &p->NumPackStreams));
|
RINOK(SzReadNumber32(sd, &p->NumPackStreams));
|
||||||
|
|
||||||
@@ -635,7 +635,7 @@ static SRes ReadUnpackInfo(CSzAr *p,
|
|||||||
CSzData *sd2,
|
CSzData *sd2,
|
||||||
UInt32 numFoldersMax,
|
UInt32 numFoldersMax,
|
||||||
const CBuf *tempBufs, UInt32 numTempBufs,
|
const CBuf *tempBufs, UInt32 numTempBufs,
|
||||||
ISzAlloc *alloc)
|
ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
CSzData sd;
|
CSzData sd;
|
||||||
|
|
||||||
@@ -934,7 +934,7 @@ static SRes SzReadStreamsInfo(CSzAr *p,
|
|||||||
UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs,
|
UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs,
|
||||||
UInt64 *dataOffset,
|
UInt64 *dataOffset,
|
||||||
CSubStreamInfo *ssi,
|
CSubStreamInfo *ssi,
|
||||||
ISzAlloc *alloc)
|
ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
UInt64 type;
|
UInt64 type;
|
||||||
|
|
||||||
@@ -976,7 +976,7 @@ static SRes SzReadAndDecodePackedStreams(
|
|||||||
UInt32 numFoldersMax,
|
UInt32 numFoldersMax,
|
||||||
UInt64 baseOffset,
|
UInt64 baseOffset,
|
||||||
CSzAr *p,
|
CSzAr *p,
|
||||||
ISzAlloc *allocTemp)
|
ISzAllocPtr allocTemp)
|
||||||
{
|
{
|
||||||
UInt64 dataStartPos;
|
UInt64 dataStartPos;
|
||||||
UInt32 fo;
|
UInt32 fo;
|
||||||
@@ -1043,7 +1043,7 @@ static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size
|
|||||||
static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
|
static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
|
||||||
CSzData *sd2,
|
CSzData *sd2,
|
||||||
const CBuf *tempBufs, UInt32 numTempBufs,
|
const CBuf *tempBufs, UInt32 numTempBufs,
|
||||||
ISzAlloc *alloc)
|
ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
CSzData sd;
|
CSzData sd;
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
@@ -1096,17 +1096,15 @@ static SRes SzReadHeader2(
|
|||||||
CSzData *sd,
|
CSzData *sd,
|
||||||
ILookInStream *inStream,
|
ILookInStream *inStream,
|
||||||
CBuf *tempBufs, UInt32 *numTempBufs,
|
CBuf *tempBufs, UInt32 *numTempBufs,
|
||||||
ISzAlloc *allocMain,
|
ISzAllocPtr allocMain,
|
||||||
ISzAlloc *allocTemp
|
ISzAllocPtr allocTemp
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UInt64 type;
|
|
||||||
UInt32 numFiles = 0;
|
|
||||||
UInt32 numEmptyStreams = 0;
|
|
||||||
CSubStreamInfo ssi;
|
CSubStreamInfo ssi;
|
||||||
const Byte *emptyStreams = NULL;
|
|
||||||
const Byte *emptyFiles = NULL;
|
|
||||||
|
|
||||||
|
{
|
||||||
|
UInt64 type;
|
||||||
|
|
||||||
SzData_Clear(&ssi.sdSizes);
|
SzData_Clear(&ssi.sdSizes);
|
||||||
SzData_Clear(&ssi.sdCRCs);
|
SzData_Clear(&ssi.sdCRCs);
|
||||||
SzData_Clear(&ssi.sdNumSubStreams);
|
SzData_Clear(&ssi.sdNumSubStreams);
|
||||||
@@ -1120,9 +1118,9 @@ static SRes SzReadHeader2(
|
|||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
UInt64 type;
|
UInt64 type2;
|
||||||
RINOK(ReadID(sd, &type));
|
RINOK(ReadID(sd, &type2));
|
||||||
if (type == k7zIdEnd)
|
if (type2 == k7zIdEnd)
|
||||||
break;
|
break;
|
||||||
RINOK(SkipData(sd));
|
RINOK(SkipData(sd));
|
||||||
}
|
}
|
||||||
@@ -1160,6 +1158,13 @@ static SRes SzReadHeader2(
|
|||||||
|
|
||||||
if (type != k7zIdFilesInfo)
|
if (type != k7zIdFilesInfo)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
UInt32 numFiles = 0;
|
||||||
|
UInt32 numEmptyStreams = 0;
|
||||||
|
const Byte *emptyStreams = NULL;
|
||||||
|
const Byte *emptyFiles = NULL;
|
||||||
|
|
||||||
RINOK(SzReadNumber32(sd, &numFiles));
|
RINOK(SzReadNumber32(sd, &numFiles));
|
||||||
p->NumFiles = numFiles;
|
p->NumFiles = numFiles;
|
||||||
@@ -1458,7 +1463,7 @@ static SRes SzReadHeader2(
|
|||||||
if (ssi.sdNumSubStreams.Data && ssi.sdNumSubStreams.Size != 0)
|
if (ssi.sdNumSubStreams.Data && ssi.sdNumSubStreams.Size != 0)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1467,8 +1472,8 @@ static SRes SzReadHeader(
|
|||||||
CSzArEx *p,
|
CSzArEx *p,
|
||||||
CSzData *sd,
|
CSzData *sd,
|
||||||
ILookInStream *inStream,
|
ILookInStream *inStream,
|
||||||
ISzAlloc *allocMain,
|
ISzAllocPtr allocMain,
|
||||||
ISzAlloc *allocTemp)
|
ISzAllocPtr allocTemp)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
UInt32 numTempBufs = 0;
|
UInt32 numTempBufs = 0;
|
||||||
@@ -1496,8 +1501,8 @@ static SRes SzReadHeader(
|
|||||||
static SRes SzArEx_Open2(
|
static SRes SzArEx_Open2(
|
||||||
CSzArEx *p,
|
CSzArEx *p,
|
||||||
ILookInStream *inStream,
|
ILookInStream *inStream,
|
||||||
ISzAlloc *allocMain,
|
ISzAllocPtr allocMain,
|
||||||
ISzAlloc *allocTemp)
|
ISzAllocPtr allocTemp)
|
||||||
{
|
{
|
||||||
Byte header[k7zStartHeaderSize];
|
Byte header[k7zStartHeaderSize];
|
||||||
Int64 startArcPos;
|
Int64 startArcPos;
|
||||||
@@ -1508,7 +1513,7 @@ static SRes SzArEx_Open2(
|
|||||||
SRes res;
|
SRes res;
|
||||||
|
|
||||||
startArcPos = 0;
|
startArcPos = 0;
|
||||||
RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));
|
RINOK(ILookInStream_Seek(inStream, &startArcPos, SZ_SEEK_CUR));
|
||||||
|
|
||||||
RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
|
RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
|
||||||
|
|
||||||
@@ -1537,7 +1542,7 @@ static SRes SzArEx_Open2(
|
|||||||
|
|
||||||
{
|
{
|
||||||
Int64 pos = 0;
|
Int64 pos = 0;
|
||||||
RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
|
RINOK(ILookInStream_Seek(inStream, &pos, SZ_SEEK_END));
|
||||||
if ((UInt64)pos < startArcPos + nextHeaderOffset ||
|
if ((UInt64)pos < startArcPos + nextHeaderOffset ||
|
||||||
(UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
|
(UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
|
||||||
(UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
|
(UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
|
||||||
@@ -1618,7 +1623,7 @@ static SRes SzArEx_Open2(
|
|||||||
|
|
||||||
|
|
||||||
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
|
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
|
||||||
ISzAlloc *allocMain, ISzAlloc *allocTemp)
|
ISzAllocPtr allocMain, ISzAllocPtr allocTemp)
|
||||||
{
|
{
|
||||||
SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
|
SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
@@ -1636,8 +1641,8 @@ SRes SzArEx_Extract(
|
|||||||
size_t *outBufferSize,
|
size_t *outBufferSize,
|
||||||
size_t *offset,
|
size_t *offset,
|
||||||
size_t *outSizeProcessed,
|
size_t *outSizeProcessed,
|
||||||
ISzAlloc *allocMain,
|
ISzAllocPtr allocMain,
|
||||||
ISzAlloc *allocTemp)
|
ISzAllocPtr allocTemp)
|
||||||
{
|
{
|
||||||
UInt32 folderIndex = p->FileToFolder[fileIndex];
|
UInt32 folderIndex = p->FileToFolder[fileIndex];
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
@@ -1647,7 +1652,7 @@ SRes SzArEx_Extract(
|
|||||||
|
|
||||||
if (folderIndex == (UInt32)-1)
|
if (folderIndex == (UInt32)-1)
|
||||||
{
|
{
|
||||||
IAlloc_Free(allocMain, *tempBuf);
|
ISzAlloc_Free(allocMain, *tempBuf);
|
||||||
*blockIndex = folderIndex;
|
*blockIndex = folderIndex;
|
||||||
*tempBuf = NULL;
|
*tempBuf = NULL;
|
||||||
*outBufferSize = 0;
|
*outBufferSize = 0;
|
||||||
@@ -1659,7 +1664,7 @@ SRes SzArEx_Extract(
|
|||||||
UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
|
UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
|
||||||
/*
|
/*
|
||||||
UInt64 unpackSizeSpec =
|
UInt64 unpackSizeSpec =
|
||||||
p->UnpackPositions[p->FolderToFile[folderIndex + 1]] -
|
p->UnpackPositions[p->FolderToFile[(size_t)folderIndex + 1]] -
|
||||||
p->UnpackPositions[p->FolderToFile[folderIndex]];
|
p->UnpackPositions[p->FolderToFile[folderIndex]];
|
||||||
*/
|
*/
|
||||||
size_t unpackSize = (size_t)unpackSizeSpec;
|
size_t unpackSize = (size_t)unpackSizeSpec;
|
||||||
@@ -1667,7 +1672,7 @@ SRes SzArEx_Extract(
|
|||||||
if (unpackSize != unpackSizeSpec)
|
if (unpackSize != unpackSizeSpec)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
*blockIndex = folderIndex;
|
*blockIndex = folderIndex;
|
||||||
IAlloc_Free(allocMain, *tempBuf);
|
ISzAlloc_Free(allocMain, *tempBuf);
|
||||||
*tempBuf = NULL;
|
*tempBuf = NULL;
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
@@ -1675,7 +1680,7 @@ SRes SzArEx_Extract(
|
|||||||
*outBufferSize = unpackSize;
|
*outBufferSize = unpackSize;
|
||||||
if (unpackSize != 0)
|
if (unpackSize != 0)
|
||||||
{
|
{
|
||||||
*tempBuf = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
|
*tempBuf = (Byte *)ISzAlloc_Alloc(allocMain, unpackSize);
|
||||||
if (*tempBuf == NULL)
|
if (*tempBuf == NULL)
|
||||||
res = SZ_ERROR_MEM;
|
res = SZ_ERROR_MEM;
|
||||||
}
|
}
|
||||||
@@ -1692,7 +1697,7 @@ SRes SzArEx_Extract(
|
|||||||
{
|
{
|
||||||
UInt64 unpackPos = p->UnpackPositions[fileIndex];
|
UInt64 unpackPos = p->UnpackPositions[fileIndex];
|
||||||
*offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]);
|
*offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]);
|
||||||
*outSizeProcessed = (size_t)(p->UnpackPositions[fileIndex + 1] - unpackPos);
|
*outSizeProcessed = (size_t)(p->UnpackPositions[(size_t)fileIndex + 1] - unpackPos);
|
||||||
if (*offset + *outSizeProcessed > *outBufferSize)
|
if (*offset + *outSizeProcessed > *outBufferSize)
|
||||||
return SZ_ERROR_FAIL;
|
return SZ_ERROR_FAIL;
|
||||||
if (SzBitWithVals_Check(&p->CRCs, fileIndex))
|
if (SzBitWithVals_Check(&p->CRCs, fileIndex))
|
||||||
|
|||||||
12
C/7zBuf.c
12
C/7zBuf.c
@@ -1,5 +1,5 @@
|
|||||||
/* 7zBuf.c -- Byte Buffer
|
/* 7zBuf.c -- Byte Buffer
|
||||||
2013-01-21 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ void Buf_Init(CBuf *p)
|
|||||||
p->size = 0;
|
p->size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
|
int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
p->size = 0;
|
p->size = 0;
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
@@ -19,8 +19,8 @@ int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
|
|||||||
p->data = 0;
|
p->data = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
p->data = (Byte *)alloc->Alloc(alloc, size);
|
p->data = (Byte *)ISzAlloc_Alloc(alloc, size);
|
||||||
if (p->data != 0)
|
if (p->data)
|
||||||
{
|
{
|
||||||
p->size = size;
|
p->size = size;
|
||||||
return 1;
|
return 1;
|
||||||
@@ -28,9 +28,9 @@ int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buf_Free(CBuf *p, ISzAlloc *alloc)
|
void Buf_Free(CBuf *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->data);
|
ISzAlloc_Free(alloc, p->data);
|
||||||
p->data = 0;
|
p->data = 0;
|
||||||
p->size = 0;
|
p->size = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
10
C/7zBuf.h
10
C/7zBuf.h
@@ -1,5 +1,5 @@
|
|||||||
/* 7zBuf.h -- Byte Buffer
|
/* 7zBuf.h -- Byte Buffer
|
||||||
2013-01-18 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_BUF_H
|
#ifndef __7Z_BUF_H
|
||||||
#define __7Z_BUF_H
|
#define __7Z_BUF_H
|
||||||
@@ -15,8 +15,8 @@ typedef struct
|
|||||||
} CBuf;
|
} CBuf;
|
||||||
|
|
||||||
void Buf_Init(CBuf *p);
|
void Buf_Init(CBuf *p);
|
||||||
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
|
int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc);
|
||||||
void Buf_Free(CBuf *p, ISzAlloc *alloc);
|
void Buf_Free(CBuf *p, ISzAllocPtr alloc);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -27,8 +27,8 @@ typedef struct
|
|||||||
|
|
||||||
void DynBuf_Construct(CDynBuf *p);
|
void DynBuf_Construct(CDynBuf *p);
|
||||||
void DynBuf_SeekToBeg(CDynBuf *p);
|
void DynBuf_SeekToBeg(CDynBuf *p);
|
||||||
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);
|
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc);
|
||||||
void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);
|
void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc);
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
|
|||||||
17
C/7zBuf2.c
17
C/7zBuf2.c
@@ -1,5 +1,5 @@
|
|||||||
/* 7zBuf2.c -- Byte Buffer
|
/* 7zBuf2.c -- Byte Buffer
|
||||||
2014-08-22 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -19,19 +19,20 @@ void DynBuf_SeekToBeg(CDynBuf *p)
|
|||||||
p->pos = 0;
|
p->pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc)
|
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
if (size > p->size - p->pos)
|
if (size > p->size - p->pos)
|
||||||
{
|
{
|
||||||
size_t newSize = p->pos + size;
|
size_t newSize = p->pos + size;
|
||||||
Byte *data;
|
Byte *data;
|
||||||
newSize += newSize / 4;
|
newSize += newSize / 4;
|
||||||
data = (Byte *)alloc->Alloc(alloc, newSize);
|
data = (Byte *)ISzAlloc_Alloc(alloc, newSize);
|
||||||
if (data == 0)
|
if (!data)
|
||||||
return 0;
|
return 0;
|
||||||
p->size = newSize;
|
p->size = newSize;
|
||||||
memcpy(data, p->data, p->pos);
|
if (p->pos != 0)
|
||||||
alloc->Free(alloc, p->data);
|
memcpy(data, p->data, p->pos);
|
||||||
|
ISzAlloc_Free(alloc, p->data);
|
||||||
p->data = data;
|
p->data = data;
|
||||||
}
|
}
|
||||||
if (size != 0)
|
if (size != 0)
|
||||||
@@ -42,9 +43,9 @@ int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc)
|
void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->data);
|
ISzAlloc_Free(alloc, p->data);
|
||||||
p->data = 0;
|
p->data = 0;
|
||||||
p->size = 0;
|
p->size = 0;
|
||||||
p->pos = 0;
|
p->pos = 0;
|
||||||
|
|||||||
16
C/7zCrc.c
16
C/7zCrc.c
@@ -1,5 +1,5 @@
|
|||||||
/* 7zCrc.c -- CRC32 init
|
/* 7zCrc.c -- CRC32 init
|
||||||
2015-03-10 : Igor Pavlov : Public domain */
|
2017-06-06 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -61,12 +61,12 @@ void MY_FAST_CALL CrcGenerateTable()
|
|||||||
UInt32 r = i;
|
UInt32 r = i;
|
||||||
unsigned j;
|
unsigned j;
|
||||||
for (j = 0; j < 8; j++)
|
for (j = 0; j < 8; j++)
|
||||||
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
|
||||||
g_CrcTable[i] = r;
|
g_CrcTable[i] = r;
|
||||||
}
|
}
|
||||||
for (; i < 256 * CRC_NUM_TABLES; i++)
|
for (i = 256; i < 256 * CRC_NUM_TABLES; i++)
|
||||||
{
|
{
|
||||||
UInt32 r = g_CrcTable[i - 256];
|
UInt32 r = g_CrcTable[(size_t)i - 256];
|
||||||
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
|
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,8 +86,8 @@ void MY_FAST_CALL CrcGenerateTable()
|
|||||||
|
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
if (!CPU_Is_InOrder())
|
if (!CPU_Is_InOrder())
|
||||||
g_CrcUpdate = CrcUpdateT8;
|
|
||||||
#endif
|
#endif
|
||||||
|
g_CrcUpdate = CrcUpdateT8;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@@ -101,7 +101,7 @@ void MY_FAST_CALL CrcGenerateTable()
|
|||||||
g_CrcUpdate = CrcUpdateT4;
|
g_CrcUpdate = CrcUpdateT4;
|
||||||
#if CRC_NUM_TABLES >= 8
|
#if CRC_NUM_TABLES >= 8
|
||||||
g_CrcUpdateT8 = CrcUpdateT8;
|
g_CrcUpdateT8 = CrcUpdateT8;
|
||||||
// g_CrcUpdate = CrcUpdateT8;
|
g_CrcUpdate = CrcUpdateT8;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (p[0] != 1 || p[1] != 2)
|
else if (p[0] != 1 || p[1] != 2)
|
||||||
@@ -111,14 +111,14 @@ void MY_FAST_CALL CrcGenerateTable()
|
|||||||
{
|
{
|
||||||
for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
|
for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
|
||||||
{
|
{
|
||||||
UInt32 x = g_CrcTable[i - 256];
|
UInt32 x = g_CrcTable[(size_t)i - 256];
|
||||||
g_CrcTable[i] = CRC_UINT32_SWAP(x);
|
g_CrcTable[i] = CRC_UINT32_SWAP(x);
|
||||||
}
|
}
|
||||||
g_CrcUpdateT4 = CrcUpdateT1_BeT4;
|
g_CrcUpdateT4 = CrcUpdateT1_BeT4;
|
||||||
g_CrcUpdate = CrcUpdateT1_BeT4;
|
g_CrcUpdate = CrcUpdateT1_BeT4;
|
||||||
#if CRC_NUM_TABLES >= 8
|
#if CRC_NUM_TABLES >= 8
|
||||||
g_CrcUpdateT8 = CrcUpdateT1_BeT8;
|
g_CrcUpdateT8 = CrcUpdateT1_BeT8;
|
||||||
// g_CrcUpdate = CrcUpdateT1_BeT8;
|
g_CrcUpdate = CrcUpdateT1_BeT8;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
50
C/7zCrcOpt.c
50
C/7zCrcOpt.c
@@ -1,5 +1,5 @@
|
|||||||
/* 7zCrcOpt.c -- CRC32 calculation
|
/* 7zCrcOpt.c -- CRC32 calculation
|
||||||
2015-03-01 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -18,10 +18,10 @@ UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const U
|
|||||||
{
|
{
|
||||||
v ^= *(const UInt32 *)p;
|
v ^= *(const UInt32 *)p;
|
||||||
v =
|
v =
|
||||||
table[0x300 + ((v ) & 0xFF)]
|
(table + 0x300)[((v ) & 0xFF)]
|
||||||
^ table[0x200 + ((v >> 8) & 0xFF)]
|
^ (table + 0x200)[((v >> 8) & 0xFF)]
|
||||||
^ table[0x100 + ((v >> 16) & 0xFF)]
|
^ (table + 0x100)[((v >> 16) & 0xFF)]
|
||||||
^ table[0x000 + ((v >> 24))];
|
^ (table + 0x000)[((v >> 24))];
|
||||||
}
|
}
|
||||||
for (; size > 0; size--, p++)
|
for (; size > 0; size--, p++)
|
||||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||||
@@ -38,16 +38,16 @@ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const U
|
|||||||
UInt32 d;
|
UInt32 d;
|
||||||
v ^= *(const UInt32 *)p;
|
v ^= *(const UInt32 *)p;
|
||||||
v =
|
v =
|
||||||
table[0x700 + ((v ) & 0xFF)]
|
(table + 0x700)[((v ) & 0xFF)]
|
||||||
^ table[0x600 + ((v >> 8) & 0xFF)]
|
^ (table + 0x600)[((v >> 8) & 0xFF)]
|
||||||
^ table[0x500 + ((v >> 16) & 0xFF)]
|
^ (table + 0x500)[((v >> 16) & 0xFF)]
|
||||||
^ table[0x400 + ((v >> 24))];
|
^ (table + 0x400)[((v >> 24))];
|
||||||
d = *((const UInt32 *)p + 1);
|
d = *((const UInt32 *)p + 1);
|
||||||
v ^=
|
v ^=
|
||||||
table[0x300 + ((d ) & 0xFF)]
|
(table + 0x300)[((d ) & 0xFF)]
|
||||||
^ table[0x200 + ((d >> 8) & 0xFF)]
|
^ (table + 0x200)[((d >> 8) & 0xFF)]
|
||||||
^ table[0x100 + ((d >> 16) & 0xFF)]
|
^ (table + 0x100)[((d >> 16) & 0xFF)]
|
||||||
^ table[0x000 + ((d >> 24))];
|
^ (table + 0x000)[((d >> 24))];
|
||||||
}
|
}
|
||||||
for (; size > 0; size--, p++)
|
for (; size > 0; size--, p++)
|
||||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||||
@@ -74,10 +74,10 @@ UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, co
|
|||||||
{
|
{
|
||||||
v ^= *(const UInt32 *)p;
|
v ^= *(const UInt32 *)p;
|
||||||
v =
|
v =
|
||||||
table[0x000 + ((v ) & 0xFF)]
|
(table + 0x000)[((v ) & 0xFF)]
|
||||||
^ table[0x100 + ((v >> 8) & 0xFF)]
|
^ (table + 0x100)[((v >> 8) & 0xFF)]
|
||||||
^ table[0x200 + ((v >> 16) & 0xFF)]
|
^ (table + 0x200)[((v >> 16) & 0xFF)]
|
||||||
^ table[0x300 + ((v >> 24))];
|
^ (table + 0x300)[((v >> 24))];
|
||||||
}
|
}
|
||||||
for (; size > 0; size--, p++)
|
for (; size > 0; size--, p++)
|
||||||
v = CRC_UPDATE_BYTE_2_BE(v, *p);
|
v = CRC_UPDATE_BYTE_2_BE(v, *p);
|
||||||
@@ -96,16 +96,16 @@ UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, co
|
|||||||
UInt32 d;
|
UInt32 d;
|
||||||
v ^= *(const UInt32 *)p;
|
v ^= *(const UInt32 *)p;
|
||||||
v =
|
v =
|
||||||
table[0x400 + ((v ) & 0xFF)]
|
(table + 0x400)[((v ) & 0xFF)]
|
||||||
^ table[0x500 + ((v >> 8) & 0xFF)]
|
^ (table + 0x500)[((v >> 8) & 0xFF)]
|
||||||
^ table[0x600 + ((v >> 16) & 0xFF)]
|
^ (table + 0x600)[((v >> 16) & 0xFF)]
|
||||||
^ table[0x700 + ((v >> 24))];
|
^ (table + 0x700)[((v >> 24))];
|
||||||
d = *((const UInt32 *)p + 1);
|
d = *((const UInt32 *)p + 1);
|
||||||
v ^=
|
v ^=
|
||||||
table[0x000 + ((d ) & 0xFF)]
|
(table + 0x000)[((d ) & 0xFF)]
|
||||||
^ table[0x100 + ((d >> 8) & 0xFF)]
|
^ (table + 0x100)[((d >> 8) & 0xFF)]
|
||||||
^ table[0x200 + ((d >> 16) & 0xFF)]
|
^ (table + 0x200)[((d >> 16) & 0xFF)]
|
||||||
^ table[0x300 + ((d >> 24))];
|
^ (table + 0x300)[((d >> 24))];
|
||||||
}
|
}
|
||||||
for (; size > 0; size--, p++)
|
for (; size > 0; size--, p++)
|
||||||
v = CRC_UPDATE_BYTE_2_BE(v, *p);
|
v = CRC_UPDATE_BYTE_2_BE(v, *p);
|
||||||
|
|||||||
54
C/7zDec.c
54
C/7zDec.c
@@ -1,5 +1,5 @@
|
|||||||
/* 7zDec.c -- Decoding from 7z folder
|
/* 7zDec.c -- Decoding from 7z folder
|
||||||
2015-11-18 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -39,28 +39,28 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IByteIn p;
|
IByteIn vt;
|
||||||
const Byte *cur;
|
const Byte *cur;
|
||||||
const Byte *end;
|
const Byte *end;
|
||||||
const Byte *begin;
|
const Byte *begin;
|
||||||
UInt64 processed;
|
UInt64 processed;
|
||||||
Bool extra;
|
Bool extra;
|
||||||
SRes res;
|
SRes res;
|
||||||
ILookInStream *inStream;
|
const ILookInStream *inStream;
|
||||||
} CByteInToLook;
|
} CByteInToLook;
|
||||||
|
|
||||||
static Byte ReadByte(void *pp)
|
static Byte ReadByte(const IByteIn *pp)
|
||||||
{
|
{
|
||||||
CByteInToLook *p = (CByteInToLook *)pp;
|
CByteInToLook *p = CONTAINER_FROM_VTBL(pp, CByteInToLook, vt);
|
||||||
if (p->cur != p->end)
|
if (p->cur != p->end)
|
||||||
return *p->cur++;
|
return *p->cur++;
|
||||||
if (p->res == SZ_OK)
|
if (p->res == SZ_OK)
|
||||||
{
|
{
|
||||||
size_t size = p->cur - p->begin;
|
size_t size = p->cur - p->begin;
|
||||||
p->processed += size;
|
p->processed += size;
|
||||||
p->res = p->inStream->Skip(p->inStream, size);
|
p->res = ILookInStream_Skip(p->inStream, size);
|
||||||
size = (1 << 25);
|
size = (1 << 25);
|
||||||
p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size);
|
p->res = ILookInStream_Look(p->inStream, (const void **)&p->begin, &size);
|
||||||
p->cur = p->begin;
|
p->cur = p->begin;
|
||||||
p->end = p->begin + size;
|
p->end = p->begin + size;
|
||||||
if (size != 0)
|
if (size != 0)
|
||||||
@@ -70,14 +70,14 @@ static Byte ReadByte(void *pp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
|
static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, const ILookInStream *inStream,
|
||||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
|
||||||
{
|
{
|
||||||
CPpmd7 ppmd;
|
CPpmd7 ppmd;
|
||||||
CByteInToLook s;
|
CByteInToLook s;
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
|
|
||||||
s.p.Read = ReadByte;
|
s.vt.Read = ReadByte;
|
||||||
s.inStream = inStream;
|
s.inStream = inStream;
|
||||||
s.begin = s.end = s.cur = NULL;
|
s.begin = s.end = s.cur = NULL;
|
||||||
s.extra = False;
|
s.extra = False;
|
||||||
@@ -103,7 +103,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I
|
|||||||
{
|
{
|
||||||
CPpmd7z_RangeDec rc;
|
CPpmd7z_RangeDec rc;
|
||||||
Ppmd7z_RangeDec_CreateVTable(&rc);
|
Ppmd7z_RangeDec_CreateVTable(&rc);
|
||||||
rc.Stream = &s.p;
|
rc.Stream = &s.vt;
|
||||||
if (!Ppmd7z_RangeDec_Init(&rc))
|
if (!Ppmd7z_RangeDec_Init(&rc))
|
||||||
res = SZ_ERROR_DATA;
|
res = SZ_ERROR_DATA;
|
||||||
else if (s.extra)
|
else if (s.extra)
|
||||||
@@ -113,7 +113,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I
|
|||||||
SizeT i;
|
SizeT i;
|
||||||
for (i = 0; i < outSize; i++)
|
for (i = 0; i < outSize; i++)
|
||||||
{
|
{
|
||||||
int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);
|
int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.vt);
|
||||||
if (s.extra || sym < 0)
|
if (s.extra || sym < 0)
|
||||||
break;
|
break;
|
||||||
outBuffer[i] = (Byte)sym;
|
outBuffer[i] = (Byte)sym;
|
||||||
@@ -132,7 +132,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I
|
|||||||
|
|
||||||
|
|
||||||
static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
|
static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
|
||||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
|
||||||
{
|
{
|
||||||
CLzmaDec state;
|
CLzmaDec state;
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
@@ -149,7 +149,7 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
|
|||||||
size_t lookahead = (1 << 18);
|
size_t lookahead = (1 << 18);
|
||||||
if (lookahead > inSize)
|
if (lookahead > inSize)
|
||||||
lookahead = (size_t)inSize;
|
lookahead = (size_t)inSize;
|
||||||
res = inStream->Look(inStream, &inBuf, &lookahead);
|
res = ILookInStream_Look(inStream, &inBuf, &lookahead);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -178,7 +178,7 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = inStream->Skip((void *)inStream, inProcessed);
|
res = ILookInStream_Skip(inStream, inProcessed);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -192,7 +192,7 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
|
|||||||
#ifndef _7Z_NO_METHOD_LZMA2
|
#ifndef _7Z_NO_METHOD_LZMA2
|
||||||
|
|
||||||
static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
|
static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
|
||||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
|
||||||
{
|
{
|
||||||
CLzma2Dec state;
|
CLzma2Dec state;
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
@@ -211,7 +211,7 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
|
|||||||
size_t lookahead = (1 << 18);
|
size_t lookahead = (1 << 18);
|
||||||
if (lookahead > inSize)
|
if (lookahead > inSize)
|
||||||
lookahead = (size_t)inSize;
|
lookahead = (size_t)inSize;
|
||||||
res = inStream->Look(inStream, &inBuf, &lookahead);
|
res = ILookInStream_Look(inStream, &inBuf, &lookahead);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -237,7 +237,7 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = inStream->Skip((void *)inStream, inProcessed);
|
res = ILookInStream_Skip(inStream, inProcessed);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -258,13 +258,13 @@ static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer
|
|||||||
size_t curSize = (1 << 18);
|
size_t curSize = (1 << 18);
|
||||||
if (curSize > inSize)
|
if (curSize > inSize)
|
||||||
curSize = (size_t)inSize;
|
curSize = (size_t)inSize;
|
||||||
RINOK(inStream->Look(inStream, &inBuf, &curSize));
|
RINOK(ILookInStream_Look(inStream, &inBuf, &curSize));
|
||||||
if (curSize == 0)
|
if (curSize == 0)
|
||||||
return SZ_ERROR_INPUT_EOF;
|
return SZ_ERROR_INPUT_EOF;
|
||||||
memcpy(outBuffer, inBuf, curSize);
|
memcpy(outBuffer, inBuf, curSize);
|
||||||
outBuffer += curSize;
|
outBuffer += curSize;
|
||||||
inSize -= curSize;
|
inSize -= curSize;
|
||||||
RINOK(inStream->Skip((void *)inStream, curSize));
|
RINOK(ILookInStream_Skip(inStream, curSize));
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
@@ -372,7 +372,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
|
|||||||
const UInt64 *unpackSizes,
|
const UInt64 *unpackSizes,
|
||||||
const UInt64 *packPositions,
|
const UInt64 *packPositions,
|
||||||
ILookInStream *inStream, UInt64 startPos,
|
ILookInStream *inStream, UInt64 startPos,
|
||||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
|
Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain,
|
||||||
Byte *tempBuf[])
|
Byte *tempBuf[])
|
||||||
{
|
{
|
||||||
UInt32 ci;
|
UInt32 ci;
|
||||||
@@ -404,7 +404,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
|
|||||||
outSizeCur = (SizeT)unpackSize;
|
outSizeCur = (SizeT)unpackSize;
|
||||||
if (outSizeCur != unpackSize)
|
if (outSizeCur != unpackSize)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
|
temp = (Byte *)ISzAlloc_Alloc(allocMain, outSizeCur);
|
||||||
if (!temp && outSizeCur != 0)
|
if (!temp && outSizeCur != 0)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
outBufCur = tempBuf[1 - ci] = temp;
|
outBufCur = tempBuf[1 - ci] = temp;
|
||||||
@@ -421,7 +421,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
|
|||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
offset = packPositions[si];
|
offset = packPositions[si];
|
||||||
inSize = packPositions[si + 1] - offset;
|
inSize = packPositions[(size_t)si + 1] - offset;
|
||||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||||
|
|
||||||
if (coder->MethodID == k_Copy)
|
if (coder->MethodID == k_Copy)
|
||||||
@@ -460,7 +460,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
|
|||||||
tempSizes[2] = (SizeT)s3Size;
|
tempSizes[2] = (SizeT)s3Size;
|
||||||
if (tempSizes[2] != s3Size)
|
if (tempSizes[2] != s3Size)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
|
tempBuf[2] = (Byte *)ISzAlloc_Alloc(allocMain, tempSizes[2]);
|
||||||
if (!tempBuf[2] && tempSizes[2] != 0)
|
if (!tempBuf[2] && tempSizes[2] != 0)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
|
|
||||||
@@ -549,7 +549,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
|
|||||||
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
|
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
|
||||||
ILookInStream *inStream, UInt64 startPos,
|
ILookInStream *inStream, UInt64 startPos,
|
||||||
Byte *outBuffer, size_t outSize,
|
Byte *outBuffer, size_t outSize,
|
||||||
ISzAlloc *allocMain)
|
ISzAllocPtr allocMain)
|
||||||
{
|
{
|
||||||
SRes res;
|
SRes res;
|
||||||
CSzFolder folder;
|
CSzFolder folder;
|
||||||
@@ -557,7 +557,7 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
|
|||||||
|
|
||||||
const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
|
const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
|
||||||
sd.Data = data;
|
sd.Data = data;
|
||||||
sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex];
|
sd.Size = p->FoCodersOffsets[(size_t)folderIndex + 1] - p->FoCodersOffsets[folderIndex];
|
||||||
|
|
||||||
res = SzGetNextFolderItem(&folder, &sd);
|
res = SzGetNextFolderItem(&folder, &sd);
|
||||||
|
|
||||||
@@ -579,7 +579,7 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
|
|||||||
outBuffer, (SizeT)outSize, allocMain, tempBuf);
|
outBuffer, (SizeT)outSize, allocMain, tempBuf);
|
||||||
|
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
IAlloc_Free(allocMain, tempBuf[i]);
|
ISzAlloc_Free(allocMain, tempBuf[i]);
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
|
if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
|
||||||
|
|||||||
26
C/7zFile.c
26
C/7zFile.c
@@ -1,5 +1,5 @@
|
|||||||
/* 7zFile.c -- File IO
|
/* 7zFile.c -- File IO
|
||||||
2009-11-24 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -238,49 +238,49 @@ WRes File_GetLength(CSzFile *p, UInt64 *length)
|
|||||||
|
|
||||||
/* ---------- FileSeqInStream ---------- */
|
/* ---------- FileSeqInStream ---------- */
|
||||||
|
|
||||||
static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)
|
static SRes FileSeqInStream_Read(const ISeqInStream *pp, void *buf, size_t *size)
|
||||||
{
|
{
|
||||||
CFileSeqInStream *p = (CFileSeqInStream *)pp;
|
CFileSeqInStream *p = CONTAINER_FROM_VTBL(pp, CFileSeqInStream, vt);
|
||||||
return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
|
return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
|
void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
|
||||||
{
|
{
|
||||||
p->s.Read = FileSeqInStream_Read;
|
p->vt.Read = FileSeqInStream_Read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ---------- FileInStream ---------- */
|
/* ---------- FileInStream ---------- */
|
||||||
|
|
||||||
static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
|
static SRes FileInStream_Read(const ISeekInStream *pp, void *buf, size_t *size)
|
||||||
{
|
{
|
||||||
CFileInStream *p = (CFileInStream *)pp;
|
CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt);
|
||||||
return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
|
return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
|
static SRes FileInStream_Seek(const ISeekInStream *pp, Int64 *pos, ESzSeek origin)
|
||||||
{
|
{
|
||||||
CFileInStream *p = (CFileInStream *)pp;
|
CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt);
|
||||||
return File_Seek(&p->file, pos, origin);
|
return File_Seek(&p->file, pos, origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileInStream_CreateVTable(CFileInStream *p)
|
void FileInStream_CreateVTable(CFileInStream *p)
|
||||||
{
|
{
|
||||||
p->s.Read = FileInStream_Read;
|
p->vt.Read = FileInStream_Read;
|
||||||
p->s.Seek = FileInStream_Seek;
|
p->vt.Seek = FileInStream_Seek;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ---------- FileOutStream ---------- */
|
/* ---------- FileOutStream ---------- */
|
||||||
|
|
||||||
static size_t FileOutStream_Write(void *pp, const void *data, size_t size)
|
static size_t FileOutStream_Write(const ISeqOutStream *pp, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
CFileOutStream *p = (CFileOutStream *)pp;
|
CFileOutStream *p = CONTAINER_FROM_VTBL(pp, CFileOutStream, vt);
|
||||||
File_Write(&p->file, data, &size);
|
File_Write(&p->file, data, &size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileOutStream_CreateVTable(CFileOutStream *p)
|
void FileOutStream_CreateVTable(CFileOutStream *p)
|
||||||
{
|
{
|
||||||
p->s.Write = FileOutStream_Write;
|
p->vt.Write = FileOutStream_Write;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* 7zFile.h -- File IO
|
/* 7zFile.h -- File IO
|
||||||
2013-01-18 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_FILE_H
|
#ifndef __7Z_FILE_H
|
||||||
#define __7Z_FILE_H
|
#define __7Z_FILE_H
|
||||||
@@ -54,7 +54,7 @@ WRes File_GetLength(CSzFile *p, UInt64 *length);
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ISeqInStream s;
|
ISeqInStream vt;
|
||||||
CSzFile file;
|
CSzFile file;
|
||||||
} CFileSeqInStream;
|
} CFileSeqInStream;
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ISeekInStream s;
|
ISeekInStream vt;
|
||||||
CSzFile file;
|
CSzFile file;
|
||||||
} CFileInStream;
|
} CFileInStream;
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ void FileInStream_CreateVTable(CFileInStream *p);
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ISeqOutStream s;
|
ISeqOutStream vt;
|
||||||
CSzFile file;
|
CSzFile file;
|
||||||
} CFileOutStream;
|
} CFileOutStream;
|
||||||
|
|
||||||
|
|||||||
111
C/7zStream.c
111
C/7zStream.c
@@ -1,5 +1,5 @@
|
|||||||
/* 7zStream.c -- 7z Stream functions
|
/* 7zStream.c -- 7z Stream functions
|
||||||
2013-11-12 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -7,12 +7,12 @@
|
|||||||
|
|
||||||
#include "7zTypes.h"
|
#include "7zTypes.h"
|
||||||
|
|
||||||
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
|
SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType)
|
||||||
{
|
{
|
||||||
while (size != 0)
|
while (size != 0)
|
||||||
{
|
{
|
||||||
size_t processed = size;
|
size_t processed = size;
|
||||||
RINOK(stream->Read(stream, buf, &processed));
|
RINOK(ISeqInStream_Read(stream, buf, &processed));
|
||||||
if (processed == 0)
|
if (processed == 0)
|
||||||
return errorType;
|
return errorType;
|
||||||
buf = (void *)((Byte *)buf + processed);
|
buf = (void *)((Byte *)buf + processed);
|
||||||
@@ -21,40 +21,42 @@ SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorT
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
|
SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size)
|
||||||
{
|
{
|
||||||
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
|
SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf)
|
||||||
{
|
{
|
||||||
size_t processed = 1;
|
size_t processed = 1;
|
||||||
RINOK(stream->Read(stream, buf, &processed));
|
RINOK(ISeqInStream_Read(stream, buf, &processed));
|
||||||
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
|
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
|
|
||||||
|
|
||||||
|
SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset)
|
||||||
{
|
{
|
||||||
Int64 t = offset;
|
Int64 t = offset;
|
||||||
return stream->Seek(stream, &t, SZ_SEEK_SET);
|
return ILookInStream_Seek(stream, &t, SZ_SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
|
SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size)
|
||||||
{
|
{
|
||||||
const void *lookBuf;
|
const void *lookBuf;
|
||||||
if (*size == 0)
|
if (*size == 0)
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
RINOK(stream->Look(stream, &lookBuf, size));
|
RINOK(ILookInStream_Look(stream, &lookBuf, size));
|
||||||
memcpy(buf, lookBuf, *size);
|
memcpy(buf, lookBuf, *size);
|
||||||
return stream->Skip(stream, *size);
|
return ILookInStream_Skip(stream, *size);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
|
SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType)
|
||||||
{
|
{
|
||||||
while (size != 0)
|
while (size != 0)
|
||||||
{
|
{
|
||||||
size_t processed = size;
|
size_t processed = size;
|
||||||
RINOK(stream->Read(stream, buf, &processed));
|
RINOK(ILookInStream_Read(stream, buf, &processed));
|
||||||
if (processed == 0)
|
if (processed == 0)
|
||||||
return errorType;
|
return errorType;
|
||||||
buf = (void *)((Byte *)buf + processed);
|
buf = (void *)((Byte *)buf + processed);
|
||||||
@@ -63,61 +65,67 @@ SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes erro
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
|
SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size)
|
||||||
{
|
{
|
||||||
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
|
|
||||||
|
|
||||||
|
#define GET_LookToRead2 CLookToRead2 *p = CONTAINER_FROM_VTBL(pp, CLookToRead2, vt);
|
||||||
|
|
||||||
|
static SRes LookToRead2_Look_Lookahead(const ILookInStream *pp, const void **buf, size_t *size)
|
||||||
{
|
{
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
CLookToRead *p = (CLookToRead *)pp;
|
GET_LookToRead2
|
||||||
size_t size2 = p->size - p->pos;
|
size_t size2 = p->size - p->pos;
|
||||||
if (size2 == 0 && *size > 0)
|
if (size2 == 0 && *size != 0)
|
||||||
{
|
{
|
||||||
p->pos = 0;
|
p->pos = 0;
|
||||||
size2 = LookToRead_BUF_SIZE;
|
p->size = 0;
|
||||||
res = p->realStream->Read(p->realStream, p->buf, &size2);
|
size2 = p->bufSize;
|
||||||
|
res = ISeekInStream_Read(p->realStream, p->buf, &size2);
|
||||||
p->size = size2;
|
p->size = size2;
|
||||||
}
|
}
|
||||||
if (size2 < *size)
|
if (*size > size2)
|
||||||
*size = size2;
|
*size = size2;
|
||||||
*buf = p->buf + p->pos;
|
*buf = p->buf + p->pos;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size)
|
static SRes LookToRead2_Look_Exact(const ILookInStream *pp, const void **buf, size_t *size)
|
||||||
{
|
{
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
CLookToRead *p = (CLookToRead *)pp;
|
GET_LookToRead2
|
||||||
size_t size2 = p->size - p->pos;
|
size_t size2 = p->size - p->pos;
|
||||||
if (size2 == 0 && *size > 0)
|
if (size2 == 0 && *size != 0)
|
||||||
{
|
{
|
||||||
p->pos = 0;
|
p->pos = 0;
|
||||||
if (*size > LookToRead_BUF_SIZE)
|
p->size = 0;
|
||||||
*size = LookToRead_BUF_SIZE;
|
if (*size > p->bufSize)
|
||||||
res = p->realStream->Read(p->realStream, p->buf, size);
|
*size = p->bufSize;
|
||||||
|
res = ISeekInStream_Read(p->realStream, p->buf, size);
|
||||||
size2 = p->size = *size;
|
size2 = p->size = *size;
|
||||||
}
|
}
|
||||||
if (size2 < *size)
|
if (*size > size2)
|
||||||
*size = size2;
|
*size = size2;
|
||||||
*buf = p->buf + p->pos;
|
*buf = p->buf + p->pos;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes LookToRead_Skip(void *pp, size_t offset)
|
static SRes LookToRead2_Skip(const ILookInStream *pp, size_t offset)
|
||||||
{
|
{
|
||||||
CLookToRead *p = (CLookToRead *)pp;
|
GET_LookToRead2
|
||||||
p->pos += offset;
|
p->pos += offset;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
|
static SRes LookToRead2_Read(const ILookInStream *pp, void *buf, size_t *size)
|
||||||
{
|
{
|
||||||
CLookToRead *p = (CLookToRead *)pp;
|
GET_LookToRead2
|
||||||
size_t rem = p->size - p->pos;
|
size_t rem = p->size - p->pos;
|
||||||
if (rem == 0)
|
if (rem == 0)
|
||||||
return p->realStream->Read(p->realStream, buf, size);
|
return ISeekInStream_Read(p->realStream, buf, size);
|
||||||
if (rem > *size)
|
if (rem > *size)
|
||||||
rem = *size;
|
rem = *size;
|
||||||
memcpy(buf, p->buf + p->pos, rem);
|
memcpy(buf, p->buf + p->pos, rem);
|
||||||
@@ -126,46 +134,43 @@ static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
|
static SRes LookToRead2_Seek(const ILookInStream *pp, Int64 *pos, ESzSeek origin)
|
||||||
{
|
{
|
||||||
CLookToRead *p = (CLookToRead *)pp;
|
GET_LookToRead2
|
||||||
p->pos = p->size = 0;
|
p->pos = p->size = 0;
|
||||||
return p->realStream->Seek(p->realStream, pos, origin);
|
return ISeekInStream_Seek(p->realStream, pos, origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
|
void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead)
|
||||||
{
|
{
|
||||||
p->s.Look = lookahead ?
|
p->vt.Look = lookahead ?
|
||||||
LookToRead_Look_Lookahead :
|
LookToRead2_Look_Lookahead :
|
||||||
LookToRead_Look_Exact;
|
LookToRead2_Look_Exact;
|
||||||
p->s.Skip = LookToRead_Skip;
|
p->vt.Skip = LookToRead2_Skip;
|
||||||
p->s.Read = LookToRead_Read;
|
p->vt.Read = LookToRead2_Read;
|
||||||
p->s.Seek = LookToRead_Seek;
|
p->vt.Seek = LookToRead2_Seek;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LookToRead_Init(CLookToRead *p)
|
|
||||||
{
|
|
||||||
p->pos = p->size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
|
|
||||||
|
static SRes SecToLook_Read(const ISeqInStream *pp, void *buf, size_t *size)
|
||||||
{
|
{
|
||||||
CSecToLook *p = (CSecToLook *)pp;
|
CSecToLook *p = CONTAINER_FROM_VTBL(pp, CSecToLook, vt);
|
||||||
return LookInStream_LookRead(p->realStream, buf, size);
|
return LookInStream_LookRead(p->realStream, buf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecToLook_CreateVTable(CSecToLook *p)
|
void SecToLook_CreateVTable(CSecToLook *p)
|
||||||
{
|
{
|
||||||
p->s.Read = SecToLook_Read;
|
p->vt.Read = SecToLook_Read;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
|
static SRes SecToRead_Read(const ISeqInStream *pp, void *buf, size_t *size)
|
||||||
{
|
{
|
||||||
CSecToRead *p = (CSecToRead *)pp;
|
CSecToRead *p = CONTAINER_FROM_VTBL(pp, CSecToRead, vt);
|
||||||
return p->realStream->Read(p->realStream, buf, size);
|
return ILookInStream_Read(p->realStream, buf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecToRead_CreateVTable(CSecToRead *p)
|
void SecToRead_CreateVTable(CSecToRead *p)
|
||||||
{
|
{
|
||||||
p->s.Read = SecToRead_Read;
|
p->vt.Read = SecToRead_Read;
|
||||||
}
|
}
|
||||||
|
|||||||
224
C/7zTypes.h
224
C/7zTypes.h
@@ -1,5 +1,5 @@
|
|||||||
/* 7zTypes.h -- Basic types
|
/* 7zTypes.h -- Basic types
|
||||||
2013-11-12 : Igor Pavlov : Public domain */
|
2017-07-17 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_TYPES_H
|
#ifndef __7Z_TYPES_H
|
||||||
#define __7Z_TYPES_H
|
#define __7Z_TYPES_H
|
||||||
@@ -42,13 +42,23 @@ EXTERN_C_BEGIN
|
|||||||
|
|
||||||
typedef int SRes;
|
typedef int SRes;
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
/* typedef DWORD WRes; */
|
/* typedef DWORD WRes; */
|
||||||
typedef unsigned WRes;
|
typedef unsigned WRes;
|
||||||
|
#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
typedef int WRes;
|
typedef int WRes;
|
||||||
|
#define MY__FACILITY_WIN32 7
|
||||||
|
#define MY__FACILITY__WRes MY__FACILITY_WIN32
|
||||||
|
#define MY_SRes_HRESULT_FROM_WRes(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (MY__FACILITY__WRes << 16) | 0x80000000)))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef RINOK
|
#ifndef RINOK
|
||||||
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
||||||
#endif
|
#endif
|
||||||
@@ -112,48 +122,72 @@ typedef int Bool;
|
|||||||
#define MY_NO_INLINE
|
#define MY_NO_INLINE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MY_FORCE_INLINE __forceinline
|
||||||
|
|
||||||
#define MY_CDECL __cdecl
|
#define MY_CDECL __cdecl
|
||||||
#define MY_FAST_CALL __fastcall
|
#define MY_FAST_CALL __fastcall
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define MY_NO_INLINE
|
#define MY_NO_INLINE
|
||||||
|
#define MY_FORCE_INLINE
|
||||||
#define MY_CDECL
|
#define MY_CDECL
|
||||||
#define MY_FAST_CALL
|
#define MY_FAST_CALL
|
||||||
|
|
||||||
|
/* inline keyword : for C++ / C99 */
|
||||||
|
|
||||||
|
/* GCC, clang: */
|
||||||
|
/*
|
||||||
|
#if defined (__GNUC__) && (__GNUC__ >= 4)
|
||||||
|
#define MY_FORCE_INLINE __attribute__((always_inline))
|
||||||
|
#define MY_NO_INLINE __attribute__((noinline))
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* The following interfaces use first parameter as pointer to structure */
|
/* The following interfaces use first parameter as pointer to structure */
|
||||||
|
|
||||||
typedef struct
|
typedef struct IByteIn IByteIn;
|
||||||
|
struct IByteIn
|
||||||
{
|
{
|
||||||
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
|
Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */
|
||||||
} IByteIn;
|
};
|
||||||
|
#define IByteIn_Read(p) (p)->Read(p)
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
void (*Write)(void *p, Byte b);
|
|
||||||
} IByteOut;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct IByteOut IByteOut;
|
||||||
|
struct IByteOut
|
||||||
{
|
{
|
||||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
void (*Write)(const IByteOut *p, Byte b);
|
||||||
|
};
|
||||||
|
#define IByteOut_Write(p, b) (p)->Write(p, b)
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct ISeqInStream ISeqInStream;
|
||||||
|
struct ISeqInStream
|
||||||
|
{
|
||||||
|
SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size);
|
||||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||||
(output(*size) < input(*size)) is allowed */
|
(output(*size) < input(*size)) is allowed */
|
||||||
} ISeqInStream;
|
};
|
||||||
|
#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
|
||||||
|
|
||||||
/* it can return SZ_ERROR_INPUT_EOF */
|
/* it can return SZ_ERROR_INPUT_EOF */
|
||||||
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
|
SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size);
|
||||||
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
|
SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType);
|
||||||
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
|
SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf);
|
||||||
|
|
||||||
typedef struct
|
|
||||||
|
typedef struct ISeqOutStream ISeqOutStream;
|
||||||
|
struct ISeqOutStream
|
||||||
{
|
{
|
||||||
size_t (*Write)(void *p, const void *buf, size_t size);
|
size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size);
|
||||||
/* Returns: result - the number of actually written bytes.
|
/* Returns: result - the number of actually written bytes.
|
||||||
(result < size) means error */
|
(result < size) means error */
|
||||||
} ISeqOutStream;
|
};
|
||||||
|
#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@@ -162,78 +196,162 @@ typedef enum
|
|||||||
SZ_SEEK_END = 2
|
SZ_SEEK_END = 2
|
||||||
} ESzSeek;
|
} ESzSeek;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
|
||||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
|
||||||
} ISeekInStream;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct ISeekInStream ISeekInStream;
|
||||||
|
struct ISeekInStream
|
||||||
{
|
{
|
||||||
SRes (*Look)(void *p, const void **buf, size_t *size);
|
SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
||||||
|
SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin);
|
||||||
|
};
|
||||||
|
#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size)
|
||||||
|
#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct ILookInStream ILookInStream;
|
||||||
|
struct ILookInStream
|
||||||
|
{
|
||||||
|
SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size);
|
||||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||||
(output(*size) > input(*size)) is not allowed
|
(output(*size) > input(*size)) is not allowed
|
||||||
(output(*size) < input(*size)) is allowed */
|
(output(*size) < input(*size)) is allowed */
|
||||||
SRes (*Skip)(void *p, size_t offset);
|
SRes (*Skip)(const ILookInStream *p, size_t offset);
|
||||||
/* offset must be <= output(*size) of Look */
|
/* offset must be <= output(*size) of Look */
|
||||||
|
|
||||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
SRes (*Read)(const ILookInStream *p, void *buf, size_t *size);
|
||||||
/* reads directly (without buffer). It's same as ISeqInStream::Read */
|
/* reads directly (without buffer). It's same as ISeqInStream::Read */
|
||||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin);
|
||||||
} ILookInStream;
|
};
|
||||||
|
|
||||||
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
|
#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size)
|
||||||
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
|
#define ILookInStream_Skip(p, offset) (p)->Skip(p, offset)
|
||||||
|
#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size)
|
||||||
|
#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
|
||||||
|
|
||||||
|
|
||||||
|
SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size);
|
||||||
|
SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset);
|
||||||
|
|
||||||
/* reads via ILookInStream::Read */
|
/* reads via ILookInStream::Read */
|
||||||
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
|
SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType);
|
||||||
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
|
SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size);
|
||||||
|
|
||||||
|
|
||||||
#define LookToRead_BUF_SIZE (1 << 14)
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ILookInStream s;
|
ILookInStream vt;
|
||||||
ISeekInStream *realStream;
|
const ISeekInStream *realStream;
|
||||||
|
|
||||||
size_t pos;
|
size_t pos;
|
||||||
size_t size;
|
size_t size; /* it's data size */
|
||||||
Byte buf[LookToRead_BUF_SIZE];
|
|
||||||
} CLookToRead;
|
/* the following variables must be set outside */
|
||||||
|
Byte *buf;
|
||||||
|
size_t bufSize;
|
||||||
|
} CLookToRead2;
|
||||||
|
|
||||||
|
void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
|
||||||
|
|
||||||
|
#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; }
|
||||||
|
|
||||||
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
|
|
||||||
void LookToRead_Init(CLookToRead *p);
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ISeqInStream s;
|
ISeqInStream vt;
|
||||||
ILookInStream *realStream;
|
const ILookInStream *realStream;
|
||||||
} CSecToLook;
|
} CSecToLook;
|
||||||
|
|
||||||
void SecToLook_CreateVTable(CSecToLook *p);
|
void SecToLook_CreateVTable(CSecToLook *p);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ISeqInStream s;
|
ISeqInStream vt;
|
||||||
ILookInStream *realStream;
|
const ILookInStream *realStream;
|
||||||
} CSecToRead;
|
} CSecToRead;
|
||||||
|
|
||||||
void SecToRead_CreateVTable(CSecToRead *p);
|
void SecToRead_CreateVTable(CSecToRead *p);
|
||||||
|
|
||||||
typedef struct
|
|
||||||
|
typedef struct ICompressProgress ICompressProgress;
|
||||||
|
|
||||||
|
struct ICompressProgress
|
||||||
{
|
{
|
||||||
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
|
SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize);
|
||||||
/* Returns: result. (result != SZ_OK) means break.
|
/* Returns: result. (result != SZ_OK) means break.
|
||||||
Value (UInt64)(Int64)-1 for size means unknown value. */
|
Value (UInt64)(Int64)-1 for size means unknown value. */
|
||||||
} ICompressProgress;
|
};
|
||||||
|
#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
|
||||||
|
|
||||||
typedef struct
|
|
||||||
|
|
||||||
|
typedef struct ISzAlloc ISzAlloc;
|
||||||
|
typedef const ISzAlloc * ISzAllocPtr;
|
||||||
|
|
||||||
|
struct ISzAlloc
|
||||||
{
|
{
|
||||||
void *(*Alloc)(void *p, size_t size);
|
void *(*Alloc)(ISzAllocPtr p, size_t size);
|
||||||
void (*Free)(void *p, void *address); /* address can be 0 */
|
void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */
|
||||||
} ISzAlloc;
|
};
|
||||||
|
|
||||||
|
#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
|
||||||
|
#define ISzAlloc_Free(p, a) (p)->Free(p, a)
|
||||||
|
|
||||||
|
/* deprecated */
|
||||||
|
#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
|
||||||
|
#define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MY_offsetof
|
||||||
|
#ifdef offsetof
|
||||||
|
#define MY_offsetof(type, m) offsetof(type, m)
|
||||||
|
/*
|
||||||
|
#define MY_offsetof(type, m) FIELD_OFFSET(type, m)
|
||||||
|
*/
|
||||||
|
#else
|
||||||
|
#define MY_offsetof(type, m) ((size_t)&(((type *)0)->m))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MY_container_of
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define MY_container_of(ptr, type, m) container_of(ptr, type, m)
|
||||||
|
#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
|
||||||
|
#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
|
||||||
|
#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly"
|
||||||
|
GCC 3.4.4 : classes with constructor
|
||||||
|
GCC 4.8.1 : classes with non-public variable members"
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MY_container_of(ptr, type, m) ((type *)((char *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m)))
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(ptr))
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
|
||||||
|
*/
|
||||||
|
#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m)
|
||||||
|
|
||||||
|
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
|
||||||
|
/*
|
||||||
|
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
|
||||||
#define IAlloc_Free(p, a) (p)->Free((p), a)
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,21 @@
|
|||||||
#define MY_VER_MAJOR 16
|
#define MY_VER_MAJOR 18
|
||||||
#define MY_VER_MINOR 00
|
#define MY_VER_MINOR 01
|
||||||
#define MY_VER_BUILD 0
|
#define MY_VER_BUILD 0
|
||||||
#define MY_VERSION_NUMBERS "16.00"
|
#define MY_VERSION_NUMBERS "18.01"
|
||||||
#define MY_VERSION "16.00"
|
#define MY_VERSION MY_VERSION_NUMBERS
|
||||||
#define MY_DATE "2016-05-10"
|
|
||||||
|
#ifdef MY_CPU_NAME
|
||||||
|
#define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")"
|
||||||
|
#else
|
||||||
|
#define MY_VERSION_CPU MY_VERSION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MY_DATE "2018-01-28"
|
||||||
#undef MY_COPYRIGHT
|
#undef MY_COPYRIGHT
|
||||||
#undef MY_VERSION_COPYRIGHT_DATE
|
#undef MY_VERSION_COPYRIGHT_DATE
|
||||||
#define MY_AUTHOR_NAME "Igor Pavlov"
|
#define MY_AUTHOR_NAME "Igor Pavlov"
|
||||||
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
|
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
|
||||||
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2016 Igor Pavlov"
|
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2018 Igor Pavlov"
|
||||||
|
|
||||||
#ifdef USE_COPYRIGHT_CR
|
#ifdef USE_COPYRIGHT_CR
|
||||||
#define MY_COPYRIGHT MY_COPYRIGHT_CR
|
#define MY_COPYRIGHT MY_COPYRIGHT_CR
|
||||||
@@ -16,4 +23,5 @@
|
|||||||
#define MY_COPYRIGHT MY_COPYRIGHT_PD
|
#define MY_COPYRIGHT MY_COPYRIGHT_PD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " : " MY_COPYRIGHT " : " MY_DATE
|
#define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE
|
||||||
|
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE
|
||||||
|
|||||||
67
C/Aes.c
67
C/Aes.c
@@ -1,5 +1,5 @@
|
|||||||
/* Aes.c -- AES encryption / decryption
|
/* Aes.c -- AES encryption / decryption
|
||||||
2015-02-23 : Igor Pavlov : Public domain */
|
2017-01-24 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -49,7 +49,13 @@ static const Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0
|
|||||||
#define gb0(x) ( (x) & 0xFF)
|
#define gb0(x) ( (x) & 0xFF)
|
||||||
#define gb1(x) (((x) >> ( 8)) & 0xFF)
|
#define gb1(x) (((x) >> ( 8)) & 0xFF)
|
||||||
#define gb2(x) (((x) >> (16)) & 0xFF)
|
#define gb2(x) (((x) >> (16)) & 0xFF)
|
||||||
#define gb3(x) (((x) >> (24)) & 0xFF)
|
#define gb3(x) (((x) >> (24)))
|
||||||
|
|
||||||
|
#define gb(n, x) gb ## n(x)
|
||||||
|
|
||||||
|
#define TT(x) (T + (x << 8))
|
||||||
|
#define DD(x) (D + (x << 8))
|
||||||
|
|
||||||
|
|
||||||
void AesGenTables(void)
|
void AesGenTables(void)
|
||||||
{
|
{
|
||||||
@@ -63,10 +69,10 @@ void AesGenTables(void)
|
|||||||
UInt32 a1 = Sbox[i];
|
UInt32 a1 = Sbox[i];
|
||||||
UInt32 a2 = xtime(a1);
|
UInt32 a2 = xtime(a1);
|
||||||
UInt32 a3 = a2 ^ a1;
|
UInt32 a3 = a2 ^ a1;
|
||||||
T[ i] = Ui32(a2, a1, a1, a3);
|
TT(0)[i] = Ui32(a2, a1, a1, a3);
|
||||||
T[0x100 + i] = Ui32(a3, a2, a1, a1);
|
TT(1)[i] = Ui32(a3, a2, a1, a1);
|
||||||
T[0x200 + i] = Ui32(a1, a3, a2, a1);
|
TT(2)[i] = Ui32(a1, a3, a2, a1);
|
||||||
T[0x300 + i] = Ui32(a1, a1, a3, a2);
|
TT(3)[i] = Ui32(a1, a1, a3, a2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
UInt32 a1 = InvS[i];
|
UInt32 a1 = InvS[i];
|
||||||
@@ -77,10 +83,10 @@ void AesGenTables(void)
|
|||||||
UInt32 aB = a8 ^ a2 ^ a1;
|
UInt32 aB = a8 ^ a2 ^ a1;
|
||||||
UInt32 aD = a8 ^ a4 ^ a1;
|
UInt32 aD = a8 ^ a4 ^ a1;
|
||||||
UInt32 aE = a8 ^ a4 ^ a2;
|
UInt32 aE = a8 ^ a4 ^ a2;
|
||||||
D[ i] = Ui32(aE, a9, aD, aB);
|
DD(0)[i] = Ui32(aE, a9, aD, aB);
|
||||||
D[0x100 + i] = Ui32(aB, aE, a9, aD);
|
DD(1)[i] = Ui32(aB, aE, a9, aD);
|
||||||
D[0x200 + i] = Ui32(aD, aB, aE, a9);
|
DD(2)[i] = Ui32(aD, aB, aE, a9);
|
||||||
D[0x300 + i] = Ui32(a9, aD, aB, aE);
|
DD(3)[i] = Ui32(a9, aD, aB, aE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +105,7 @@ void AesGenTables(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define HT(i, x, s) (T + (x << 8))[gb ## x(s[(i + x) & 3])]
|
#define HT(i, x, s) TT(x)[gb(x, s[(i + x) & 3])]
|
||||||
|
|
||||||
#define HT4(m, i, s, p) m[i] = \
|
#define HT4(m, i, s, p) m[i] = \
|
||||||
HT(i, 0, s) ^ \
|
HT(i, 0, s) ^ \
|
||||||
@@ -113,11 +119,11 @@ void AesGenTables(void)
|
|||||||
HT4(m, 2, s, p); \
|
HT4(m, 2, s, p); \
|
||||||
HT4(m, 3, s, p); \
|
HT4(m, 3, s, p); \
|
||||||
|
|
||||||
#define FT(i, x) Sbox[gb ## x(m[(i + x) & 3])]
|
#define FT(i, x) Sbox[gb(x, m[(i + x) & 3])]
|
||||||
#define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i];
|
#define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i];
|
||||||
|
|
||||||
|
|
||||||
#define HD(i, x, s) (D + (x << 8))[gb ## x(s[(i - x) & 3])]
|
#define HD(i, x, s) DD(x)[gb(x, s[(i - x) & 3])]
|
||||||
|
|
||||||
#define HD4(m, i, s, p) m[i] = \
|
#define HD4(m, i, s, p) m[i] = \
|
||||||
HD(i, 0, s) ^ \
|
HD(i, 0, s) ^ \
|
||||||
@@ -131,7 +137,7 @@ void AesGenTables(void)
|
|||||||
HD4(m, 2, s, p); \
|
HD4(m, 2, s, p); \
|
||||||
HD4(m, 3, s, p); \
|
HD4(m, 3, s, p); \
|
||||||
|
|
||||||
#define FD(i, x) InvS[gb ## x(m[(i - x) & 3])]
|
#define FD(i, x) InvS[gb(x, m[(i - x) & 3])]
|
||||||
#define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i];
|
#define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i];
|
||||||
|
|
||||||
void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize)
|
void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize)
|
||||||
@@ -147,7 +153,7 @@ void MY_FAST_CALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize)
|
|||||||
|
|
||||||
for (; i < wSize; i++)
|
for (; i < wSize; i++)
|
||||||
{
|
{
|
||||||
UInt32 t = w[i - 1];
|
UInt32 t = w[(size_t)i - 1];
|
||||||
unsigned rem = i % keySize;
|
unsigned rem = i % keySize;
|
||||||
if (rem == 0)
|
if (rem == 0)
|
||||||
t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]);
|
t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]);
|
||||||
@@ -167,10 +173,10 @@ void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize)
|
|||||||
{
|
{
|
||||||
UInt32 r = w[i];
|
UInt32 r = w[i];
|
||||||
w[i] =
|
w[i] =
|
||||||
D[ Sbox[gb0(r)]] ^
|
DD(0)[Sbox[gb0(r)]] ^
|
||||||
D[0x100 + Sbox[gb1(r)]] ^
|
DD(1)[Sbox[gb1(r)]] ^
|
||||||
D[0x200 + Sbox[gb2(r)]] ^
|
DD(2)[Sbox[gb2(r)]] ^
|
||||||
D[0x300 + Sbox[gb3(r)]];
|
DD(3)[Sbox[gb3(r)]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,20 +282,25 @@ void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks)
|
|||||||
for (; numBlocks != 0; numBlocks--)
|
for (; numBlocks != 0; numBlocks--)
|
||||||
{
|
{
|
||||||
UInt32 temp[4];
|
UInt32 temp[4];
|
||||||
Byte buf[16];
|
unsigned i;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (++p[0] == 0)
|
if (++p[0] == 0)
|
||||||
p[1]++;
|
p[1]++;
|
||||||
|
|
||||||
Aes_Encode(p + 4, temp, p);
|
Aes_Encode(p + 4, temp, p);
|
||||||
|
|
||||||
SetUi32(buf, temp[0]);
|
for (i = 0; i < 4; i++, data += 4)
|
||||||
SetUi32(buf + 4, temp[1]);
|
{
|
||||||
SetUi32(buf + 8, temp[2]);
|
UInt32 t = temp[i];
|
||||||
SetUi32(buf + 12, temp[3]);
|
|
||||||
|
#ifdef MY_CPU_LE_UNALIGN
|
||||||
for (i = 0; i < 16; i++)
|
*((UInt32 *)data) ^= t;
|
||||||
*data++ ^= buf[i];
|
#else
|
||||||
|
data[0] ^= (t & 0xFF);
|
||||||
|
data[1] ^= ((t >> 8) & 0xFF);
|
||||||
|
data[2] ^= ((t >> 16) & 0xFF);
|
||||||
|
data[3] ^= ((t >> 24));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
/* AesOpt.c -- Intel's AES
|
/* AesOpt.c -- Intel's AES
|
||||||
2013-11-12 : Igor Pavlov : Public domain */
|
2017-06-08 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
#if _MSC_VER >= 1500
|
#if (_MSC_VER > 1500) || (_MSC_FULL_VER >= 150030729)
|
||||||
#define USE_INTEL_AES
|
#define USE_INTEL_AES
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
61
C/Alloc.c
61
C/Alloc.c
@@ -1,5 +1,5 @@
|
|||||||
/* Alloc.c -- Memory allocation functions
|
/* Alloc.c -- Memory allocation functions
|
||||||
2015-02-21 : Igor Pavlov : Public domain */
|
2017-06-15 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -23,11 +23,11 @@ int g_allocCountBig = 0;
|
|||||||
void *MyAlloc(size_t size)
|
void *MyAlloc(size_t size)
|
||||||
{
|
{
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return 0;
|
return NULL;
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
{
|
{
|
||||||
void *p = malloc(size);
|
void *p = malloc(size);
|
||||||
fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p);
|
fprintf(stderr, "\nAlloc %10u bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -38,7 +38,7 @@ void *MyAlloc(size_t size)
|
|||||||
void MyFree(void *address)
|
void MyFree(void *address)
|
||||||
{
|
{
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
if (address != 0)
|
if (address)
|
||||||
fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);
|
fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);
|
||||||
#endif
|
#endif
|
||||||
free(address);
|
free(address);
|
||||||
@@ -49,20 +49,20 @@ void MyFree(void *address)
|
|||||||
void *MidAlloc(size_t size)
|
void *MidAlloc(size_t size)
|
||||||
{
|
{
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return 0;
|
return NULL;
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
|
fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
|
||||||
#endif
|
#endif
|
||||||
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MidFree(void *address)
|
void MidFree(void *address)
|
||||||
{
|
{
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
if (address != 0)
|
if (address)
|
||||||
fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
|
fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
|
||||||
#endif
|
#endif
|
||||||
if (address == 0)
|
if (!address)
|
||||||
return;
|
return;
|
||||||
VirtualFree(address, 0, MEM_RELEASE);
|
VirtualFree(address, 0, MEM_RELEASE);
|
||||||
}
|
}
|
||||||
@@ -79,10 +79,10 @@ typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
|
|||||||
void SetLargePageSize()
|
void SetLargePageSize()
|
||||||
{
|
{
|
||||||
#ifdef _7ZIP_LARGE_PAGES
|
#ifdef _7ZIP_LARGE_PAGES
|
||||||
SIZE_T size = 0;
|
SIZE_T size;
|
||||||
GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
|
GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
|
||||||
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
|
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
|
||||||
if (largePageMinimum == 0)
|
if (!largePageMinimum)
|
||||||
return;
|
return;
|
||||||
size = largePageMinimum();
|
size = largePageMinimum();
|
||||||
if (size == 0 || (size & (size - 1)) != 0)
|
if (size == 0 || (size & (size - 1)) != 0)
|
||||||
@@ -95,31 +95,40 @@ void SetLargePageSize()
|
|||||||
void *BigAlloc(size_t size)
|
void *BigAlloc(size_t size)
|
||||||
{
|
{
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return 0;
|
return NULL;
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
|
fprintf(stderr, "\nAlloc_Big %10u bytes; count = %10d", size, g_allocCountBig++);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _7ZIP_LARGE_PAGES
|
#ifdef _7ZIP_LARGE_PAGES
|
||||||
if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
|
|
||||||
{
|
{
|
||||||
void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
|
SIZE_T ps = g_LargePageSize;
|
||||||
MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
|
if (ps != 0 && ps <= (1 << 30) && size > (ps / 2))
|
||||||
if (res != 0)
|
{
|
||||||
return res;
|
size_t size2;
|
||||||
|
ps--;
|
||||||
|
size2 = (size + ps) & ~ps;
|
||||||
|
if (size2 >= size)
|
||||||
|
{
|
||||||
|
void *res = VirtualAlloc(NULL, size2, MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
|
||||||
|
if (res)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
|
||||||
|
return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BigFree(void *address)
|
void BigFree(void *address)
|
||||||
{
|
{
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
if (address != 0)
|
if (address)
|
||||||
fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
|
fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (address == 0)
|
if (!address)
|
||||||
return;
|
return;
|
||||||
VirtualFree(address, 0, MEM_RELEASE);
|
VirtualFree(address, 0, MEM_RELEASE);
|
||||||
}
|
}
|
||||||
@@ -127,10 +136,10 @@ void BigFree(void *address)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
|
static void *SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
|
||||||
static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
|
static void SzFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MyFree(address); }
|
||||||
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
ISzAlloc const g_Alloc = { SzAlloc, SzFree };
|
||||||
|
|
||||||
static void *SzBigAlloc(void *p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
|
static void *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
|
||||||
static void SzBigFree(void *p, void *address) { UNUSED_VAR(p); BigFree(address); }
|
static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); BigFree(address); }
|
||||||
ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
|
ISzAlloc const g_BigAlloc = { SzBigAlloc, SzBigFree };
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Alloc.h -- Memory allocation functions
|
/* Alloc.h -- Memory allocation functions
|
||||||
2015-02-21 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __COMMON_ALLOC_H
|
#ifndef __COMMON_ALLOC_H
|
||||||
#define __COMMON_ALLOC_H
|
#define __COMMON_ALLOC_H
|
||||||
@@ -29,8 +29,8 @@ void BigFree(void *address);
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern ISzAlloc g_Alloc;
|
extern const ISzAlloc g_Alloc;
|
||||||
extern ISzAlloc g_BigAlloc;
|
extern const ISzAlloc g_BigAlloc;
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
|
|||||||
5
C/Bcj2.c
5
C/Bcj2.c
@@ -1,5 +1,5 @@
|
|||||||
/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
|
/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
|
||||||
2015-08-01 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -61,7 +61,8 @@ SRes Bcj2Dec_Decode(CBcj2Dec *p)
|
|||||||
Byte *dest = p->dest;
|
Byte *dest = p->dest;
|
||||||
if (dest == p->destLim)
|
if (dest == p->destLim)
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
*dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0];
|
*dest = p->temp[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0];
|
||||||
|
p->state++;
|
||||||
p->dest = dest + 1;
|
p->dest = dest + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Bcj2Enc.c -- BCJ2 Encoder (Converter for x86 code)
|
/* Bcj2Enc.c -- BCJ2 Encoder (Converter for x86 code)
|
||||||
2014-11-10 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -271,7 +271,7 @@ void Bcj2Enc_Encode(CBcj2Enc *p)
|
|||||||
unsigned i;
|
unsigned i;
|
||||||
p->tempPos = tempPos;
|
p->tempPos = tempPos;
|
||||||
for (i = 0; i < tempPos; i++)
|
for (i = 0; i < tempPos; i++)
|
||||||
p->temp[i] = p->temp[i + num];
|
p->temp[i] = p->temp[(size_t)i + num];
|
||||||
|
|
||||||
p->src = src;
|
p->src = src;
|
||||||
p->srcLim = srcLim;
|
p->srcLim = srcLim;
|
||||||
|
|||||||
289
C/Bra.c
289
C/Bra.c
@@ -1,135 +1,230 @@
|
|||||||
/* Bra.c -- Converters for RISC code
|
/* Bra.c -- Converters for RISC code
|
||||||
2010-04-16 : Igor Pavlov : Public domain */
|
2017-04-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
|
#include "CpuArch.h"
|
||||||
#include "Bra.h"
|
#include "Bra.h"
|
||||||
|
|
||||||
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
{
|
{
|
||||||
SizeT i;
|
Byte *p;
|
||||||
if (size < 4)
|
const Byte *lim;
|
||||||
return 0;
|
size &= ~(size_t)3;
|
||||||
size -= 4;
|
ip += 4;
|
||||||
ip += 8;
|
p = data;
|
||||||
for (i = 0; i <= size; i += 4)
|
lim = data + size;
|
||||||
|
|
||||||
|
if (encoding)
|
||||||
|
|
||||||
|
for (;;)
|
||||||
{
|
{
|
||||||
if (data[i + 3] == 0xEB)
|
for (;;)
|
||||||
{
|
{
|
||||||
UInt32 dest;
|
if (p >= lim)
|
||||||
UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
|
return p - data;
|
||||||
src <<= 2;
|
p += 4;
|
||||||
if (encoding)
|
if (p[-1] == 0xEB)
|
||||||
dest = ip + (UInt32)i + src;
|
break;
|
||||||
else
|
}
|
||||||
dest = src - (ip + (UInt32)i);
|
{
|
||||||
dest >>= 2;
|
UInt32 v = GetUi32(p - 4);
|
||||||
data[i + 2] = (Byte)(dest >> 16);
|
v <<= 2;
|
||||||
data[i + 1] = (Byte)(dest >> 8);
|
v += ip + (UInt32)(p - data);
|
||||||
data[i + 0] = (Byte)dest;
|
v >>= 2;
|
||||||
|
v &= 0x00FFFFFF;
|
||||||
|
v |= 0xEB000000;
|
||||||
|
SetUi32(p - 4, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (p >= lim)
|
||||||
|
return p - data;
|
||||||
|
p += 4;
|
||||||
|
if (p[-1] == 0xEB)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
UInt32 v = GetUi32(p - 4);
|
||||||
|
v <<= 2;
|
||||||
|
v -= ip + (UInt32)(p - data);
|
||||||
|
v >>= 2;
|
||||||
|
v &= 0x00FFFFFF;
|
||||||
|
v |= 0xEB000000;
|
||||||
|
SetUi32(p - 4, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
{
|
{
|
||||||
SizeT i;
|
Byte *p;
|
||||||
if (size < 4)
|
const Byte *lim;
|
||||||
return 0;
|
size &= ~(size_t)1;
|
||||||
size -= 4;
|
p = data;
|
||||||
ip += 4;
|
lim = data + size - 4;
|
||||||
for (i = 0; i <= size; i += 2)
|
|
||||||
|
if (encoding)
|
||||||
|
|
||||||
|
for (;;)
|
||||||
{
|
{
|
||||||
if ((data[i + 1] & 0xF8) == 0xF0 &&
|
UInt32 b1;
|
||||||
(data[i + 3] & 0xF8) == 0xF8)
|
for (;;)
|
||||||
{
|
{
|
||||||
UInt32 dest;
|
UInt32 b3;
|
||||||
UInt32 src =
|
if (p > lim)
|
||||||
(((UInt32)data[i + 1] & 0x7) << 19) |
|
return p - data;
|
||||||
((UInt32)data[i + 0] << 11) |
|
b1 = p[1];
|
||||||
(((UInt32)data[i + 3] & 0x7) << 8) |
|
b3 = p[3];
|
||||||
(data[i + 2]);
|
p += 2;
|
||||||
|
b1 ^= 8;
|
||||||
src <<= 1;
|
if ((b3 & b1) >= 0xF8)
|
||||||
if (encoding)
|
break;
|
||||||
dest = ip + (UInt32)i + src;
|
}
|
||||||
else
|
{
|
||||||
dest = src - (ip + (UInt32)i);
|
UInt32 v =
|
||||||
dest >>= 1;
|
((UInt32)b1 << 19)
|
||||||
|
+ (((UInt32)p[1] & 0x7) << 8)
|
||||||
data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
|
+ (((UInt32)p[-2] << 11))
|
||||||
data[i + 0] = (Byte)(dest >> 11);
|
+ (p[0]);
|
||||||
data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
|
|
||||||
data[i + 2] = (Byte)dest;
|
p += 2;
|
||||||
i += 2;
|
{
|
||||||
|
UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
|
||||||
|
v += cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
p[-4] = (Byte)(v >> 11);
|
||||||
|
p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
|
||||||
|
p[-2] = (Byte)v;
|
||||||
|
p[-1] = (Byte)(0xF8 | (v >> 8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
UInt32 b1;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
UInt32 b3;
|
||||||
|
if (p > lim)
|
||||||
|
return p - data;
|
||||||
|
b1 = p[1];
|
||||||
|
b3 = p[3];
|
||||||
|
p += 2;
|
||||||
|
b1 ^= 8;
|
||||||
|
if ((b3 & b1) >= 0xF8)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
UInt32 v =
|
||||||
|
((UInt32)b1 << 19)
|
||||||
|
+ (((UInt32)p[1] & 0x7) << 8)
|
||||||
|
+ (((UInt32)p[-2] << 11))
|
||||||
|
+ (p[0]);
|
||||||
|
|
||||||
|
p += 2;
|
||||||
|
{
|
||||||
|
UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
|
||||||
|
v -= cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000));
|
||||||
|
SetUi16(p - 2, (UInt16)(v | 0xF800));
|
||||||
|
*/
|
||||||
|
|
||||||
|
p[-4] = (Byte)(v >> 11);
|
||||||
|
p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
|
||||||
|
p[-2] = (Byte)v;
|
||||||
|
p[-1] = (Byte)(0xF8 | (v >> 8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
{
|
{
|
||||||
SizeT i;
|
Byte *p;
|
||||||
if (size < 4)
|
const Byte *lim;
|
||||||
return 0;
|
size &= ~(size_t)3;
|
||||||
size -= 4;
|
ip -= 4;
|
||||||
for (i = 0; i <= size; i += 4)
|
p = data;
|
||||||
|
lim = data + size;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
{
|
{
|
||||||
if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
|
for (;;)
|
||||||
{
|
{
|
||||||
UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
|
if (p >= lim)
|
||||||
((UInt32)data[i + 1] << 16) |
|
return p - data;
|
||||||
((UInt32)data[i + 2] << 8) |
|
p += 4;
|
||||||
((UInt32)data[i + 3] & (~3));
|
/* if ((v & 0xFC000003) == 0x48000001) */
|
||||||
|
if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1)
|
||||||
UInt32 dest;
|
break;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
UInt32 v = GetBe32(p - 4);
|
||||||
if (encoding)
|
if (encoding)
|
||||||
dest = ip + (UInt32)i + src;
|
v += ip + (UInt32)(p - data);
|
||||||
else
|
else
|
||||||
dest = src - (ip + (UInt32)i);
|
v -= ip + (UInt32)(p - data);
|
||||||
data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3));
|
v &= 0x03FFFFFF;
|
||||||
data[i + 1] = (Byte)(dest >> 16);
|
v |= 0x48000000;
|
||||||
data[i + 2] = (Byte)(dest >> 8);
|
SetBe32(p - 4, v);
|
||||||
data[i + 3] &= 0x3;
|
|
||||||
data[i + 3] |= dest;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
Byte *p;
|
||||||
if (size < 4)
|
const Byte *lim;
|
||||||
return 0;
|
size &= ~(size_t)3;
|
||||||
size -= 4;
|
ip -= 4;
|
||||||
for (i = 0; i <= size; i += 4)
|
p = data;
|
||||||
{
|
lim = data + size;
|
||||||
if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
|
|
||||||
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
|
|
||||||
{
|
|
||||||
UInt32 src =
|
|
||||||
((UInt32)data[i + 0] << 24) |
|
|
||||||
((UInt32)data[i + 1] << 16) |
|
|
||||||
((UInt32)data[i + 2] << 8) |
|
|
||||||
((UInt32)data[i + 3]);
|
|
||||||
UInt32 dest;
|
|
||||||
|
|
||||||
src <<= 2;
|
|
||||||
if (encoding)
|
|
||||||
dest = ip + i + src;
|
|
||||||
else
|
|
||||||
dest = src - (ip + i);
|
|
||||||
dest >>= 2;
|
|
||||||
|
|
||||||
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
|
|
||||||
|
|
||||||
data[i + 0] = (Byte)(dest >> 24);
|
for (;;)
|
||||||
data[i + 1] = (Byte)(dest >> 16);
|
{
|
||||||
data[i + 2] = (Byte)(dest >> 8);
|
for (;;)
|
||||||
data[i + 3] = (Byte)dest;
|
{
|
||||||
|
if (p >= lim)
|
||||||
|
return p - data;
|
||||||
|
/*
|
||||||
|
v = GetBe32(p);
|
||||||
|
p += 4;
|
||||||
|
m = v + ((UInt32)5 << 29);
|
||||||
|
m ^= (UInt32)7 << 29;
|
||||||
|
m += (UInt32)1 << 22;
|
||||||
|
if ((m & ((UInt32)0x1FF << 23)) == 0)
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
p += 4;
|
||||||
|
if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) ||
|
||||||
|
(p[-4] == 0x7F && (p[-3] >= 0xC0)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
UInt32 v = GetBe32(p - 4);
|
||||||
|
v <<= 2;
|
||||||
|
if (encoding)
|
||||||
|
v += ip + (UInt32)(p - data);
|
||||||
|
else
|
||||||
|
v -= ip + (UInt32)(p - data);
|
||||||
|
|
||||||
|
v &= 0x01FFFFFF;
|
||||||
|
v -= (UInt32)1 << 24;
|
||||||
|
v ^= 0xFF000000;
|
||||||
|
v >>= 2;
|
||||||
|
v |= 0x40000000;
|
||||||
|
SetBe32(p - 4, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Bra86.c -- Converter for x86 code (BCJ)
|
/* Bra86.c -- Converter for x86 code (BCJ)
|
||||||
2013-11-12 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
mask >>= (unsigned)d;
|
mask >>= (unsigned)d;
|
||||||
if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1])))
|
if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1])))
|
||||||
{
|
{
|
||||||
mask = (mask >> 1) | 4;
|
mask = (mask >> 1) | 4;
|
||||||
pos++;
|
pos++;
|
||||||
|
|||||||
82
C/BraIA64.c
82
C/BraIA64.c
@@ -1,69 +1,53 @@
|
|||||||
/* BraIA64.c -- Converter for IA-64 code
|
/* BraIA64.c -- Converter for IA-64 code
|
||||||
2013-11-12 : Igor Pavlov : Public domain */
|
2017-01-26 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
|
#include "CpuArch.h"
|
||||||
#include "Bra.h"
|
#include "Bra.h"
|
||||||
|
|
||||||
static const Byte kBranchTable[32] =
|
|
||||||
{
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
4, 4, 6, 6, 0, 0, 7, 7,
|
|
||||||
4, 4, 0, 0, 4, 4, 0, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
{
|
{
|
||||||
SizeT i;
|
SizeT i;
|
||||||
if (size < 16)
|
if (size < 16)
|
||||||
return 0;
|
return 0;
|
||||||
size -= 16;
|
size -= 16;
|
||||||
for (i = 0; i <= size; i += 16)
|
i = 0;
|
||||||
|
do
|
||||||
{
|
{
|
||||||
UInt32 instrTemplate = data[i] & 0x1F;
|
unsigned m = ((UInt32)0x334B0000 >> (data[i] & 0x1E)) & 3;
|
||||||
UInt32 mask = kBranchTable[instrTemplate];
|
if (m)
|
||||||
UInt32 bitPos = 5;
|
|
||||||
int slot;
|
|
||||||
for (slot = 0; slot < 3; slot++, bitPos += 41)
|
|
||||||
{
|
{
|
||||||
UInt32 bytePos, bitRes;
|
m++;
|
||||||
UInt64 instruction, instNorm;
|
do
|
||||||
int j;
|
|
||||||
if (((mask >> slot) & 1) == 0)
|
|
||||||
continue;
|
|
||||||
bytePos = (bitPos >> 3);
|
|
||||||
bitRes = bitPos & 0x7;
|
|
||||||
instruction = 0;
|
|
||||||
for (j = 0; j < 6; j++)
|
|
||||||
instruction += (UInt64)data[i + j + bytePos] << (8 * j);
|
|
||||||
|
|
||||||
instNorm = instruction >> bitRes;
|
|
||||||
if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0)
|
|
||||||
{
|
{
|
||||||
UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF);
|
Byte *p = data + (i + (size_t)m * 5 - 8);
|
||||||
UInt32 dest;
|
if (((p[3] >> m) & 15) == 5
|
||||||
src |= ((UInt32)(instNorm >> 36) & 1) << 20;
|
&& (((p[-1] | ((UInt32)p[0] << 8)) >> m) & 0x70) == 0)
|
||||||
|
{
|
||||||
src <<= 4;
|
unsigned raw = GetUi32(p);
|
||||||
|
unsigned v = raw >> m;
|
||||||
if (encoding)
|
v = (v & 0xFFFFF) | ((v & (1 << 23)) >> 3);
|
||||||
dest = ip + (UInt32)i + src;
|
|
||||||
else
|
v <<= 4;
|
||||||
dest = src - (ip + (UInt32)i);
|
if (encoding)
|
||||||
|
v += ip + (UInt32)i;
|
||||||
dest >>= 4;
|
else
|
||||||
|
v -= ip + (UInt32)i;
|
||||||
instNorm &= ~((UInt64)(0x8FFFFF) << 13);
|
v >>= 4;
|
||||||
instNorm |= ((UInt64)(dest & 0xFFFFF) << 13);
|
|
||||||
instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20));
|
v &= 0x1FFFFF;
|
||||||
|
v += 0x700000;
|
||||||
instruction &= (1 << bitRes) - 1;
|
v &= 0x8FFFFF;
|
||||||
instruction |= (instNorm << bitRes);
|
raw &= ~((UInt32)0x8FFFFF << m);
|
||||||
for (j = 0; j < 6; j++)
|
raw |= (v << m);
|
||||||
data[i + j + bytePos] = (Byte)(instruction >> (8 * j));
|
SetUi32(p, raw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
while (++m <= 4);
|
||||||
}
|
}
|
||||||
|
i += 16;
|
||||||
}
|
}
|
||||||
|
while (i <= size);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|||||||
20
C/BwtSort.c
20
C/BwtSort.c
@@ -1,5 +1,5 @@
|
|||||||
/* BwtSort.c -- BWT block sorting
|
/* BwtSort.c -- BWT block sorting
|
||||||
2013-11-12 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -314,7 +314,7 @@ UInt32 NO_INLINE SortGroup(UInt32 BlockSize, UInt32 NumSortedBytes, UInt32 group
|
|||||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||||
UInt32 subGroupSize = ((ind2[j] & ~0xC0000000) >> kNumBitsMax);
|
UInt32 subGroupSize = ((ind2[j] & ~0xC0000000) >> kNumBitsMax);
|
||||||
if ((ind2[j] & 0x40000000) != 0)
|
if ((ind2[j] & 0x40000000) != 0)
|
||||||
subGroupSize += ((ind2[j + 1] >> kNumBitsMax) << kNumExtra0Bits);
|
subGroupSize += ((ind2[(size_t)j + 1] >> kNumBitsMax) << kNumExtra0Bits);
|
||||||
subGroupSize++;
|
subGroupSize++;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@@ -362,7 +362,7 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
|
|||||||
for (i = 0; i < kNumHashValues; i++)
|
for (i = 0; i < kNumHashValues; i++)
|
||||||
counters[i] = 0;
|
counters[i] = 0;
|
||||||
for (i = 0; i < blockSize - 1; i++)
|
for (i = 0; i < blockSize - 1; i++)
|
||||||
counters[((UInt32)data[i] << 8) | data[i + 1]]++;
|
counters[((UInt32)data[i] << 8) | data[(size_t)i + 1]]++;
|
||||||
counters[((UInt32)data[i] << 8) | data[0]]++;
|
counters[((UInt32)data[i] << 8) | data[0]]++;
|
||||||
|
|
||||||
Groups = counters + BS_TEMP_SIZE;
|
Groups = counters + BS_TEMP_SIZE;
|
||||||
@@ -392,11 +392,11 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < blockSize - 1; i++)
|
for (i = 0; i < blockSize - 1; i++)
|
||||||
Groups[i] = counters[((UInt32)data[i] << 8) | data[i + 1]];
|
Groups[i] = counters[((UInt32)data[i] << 8) | data[(size_t)i + 1]];
|
||||||
Groups[i] = counters[((UInt32)data[i] << 8) | data[0]];
|
Groups[i] = counters[((UInt32)data[i] << 8) | data[0]];
|
||||||
|
|
||||||
for (i = 0; i < blockSize - 1; i++)
|
for (i = 0; i < blockSize - 1; i++)
|
||||||
Indices[counters[((UInt32)data[i] << 8) | data[i + 1]]++] = i;
|
Indices[counters[((UInt32)data[i] << 8) | data[(size_t)i + 1]]++] = i;
|
||||||
Indices[counters[((UInt32)data[i] << 8) | data[0]]++] = i;
|
Indices[counters[((UInt32)data[i] << 8) | data[0]]++] = i;
|
||||||
|
|
||||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||||
@@ -451,8 +451,8 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
|
|||||||
Bool finishedGroup = ((Indices[i] & 0x80000000) == 0);
|
Bool finishedGroup = ((Indices[i] & 0x80000000) == 0);
|
||||||
if ((Indices[i] & 0x40000000) != 0)
|
if ((Indices[i] & 0x40000000) != 0)
|
||||||
{
|
{
|
||||||
groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits);
|
groupSize += ((Indices[(size_t)i + 1] >> kNumBitsMax) << kNumExtra0Bits);
|
||||||
Indices[i + 1] &= kIndexMask;
|
Indices[(size_t)i + 1] &= kIndexMask;
|
||||||
}
|
}
|
||||||
Indices[i] &= kIndexMask;
|
Indices[i] &= kIndexMask;
|
||||||
groupSize++;
|
groupSize++;
|
||||||
@@ -460,7 +460,7 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
|
|||||||
{
|
{
|
||||||
Indices[i - finishedGroupSize] &= kIndexMask;
|
Indices[i - finishedGroupSize] &= kIndexMask;
|
||||||
if (finishedGroupSize > 1)
|
if (finishedGroupSize > 1)
|
||||||
Indices[i - finishedGroupSize + 1] &= kIndexMask;
|
Indices[(size_t)(i - finishedGroupSize) + 1] &= kIndexMask;
|
||||||
{
|
{
|
||||||
UInt32 newGroupSize = groupSize + finishedGroupSize;
|
UInt32 newGroupSize = groupSize + finishedGroupSize;
|
||||||
SetFinishedGroupSize(Indices + i - finishedGroupSize, newGroupSize);
|
SetFinishedGroupSize(Indices + i - finishedGroupSize, newGroupSize);
|
||||||
@@ -503,8 +503,8 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
|
|||||||
UInt32 groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax);
|
UInt32 groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax);
|
||||||
if ((Indices[i] & 0x40000000) != 0)
|
if ((Indices[i] & 0x40000000) != 0)
|
||||||
{
|
{
|
||||||
groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits);
|
groupSize += ((Indices[(size_t)i + 1] >> kNumBitsMax) << kNumExtra0Bits);
|
||||||
Indices[i + 1] &= kIndexMask;
|
Indices[(size_t)i + 1] &= kIndexMask;
|
||||||
}
|
}
|
||||||
Indices[i] &= kIndexMask;
|
Indices[i] &= kIndexMask;
|
||||||
groupSize++;
|
groupSize++;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Compiler.h
|
/* Compiler.h
|
||||||
2015-08-02 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_COMPILER_H
|
#ifndef __7Z_COMPILER_H
|
||||||
#define __7Z_COMPILER_H
|
#define __7Z_COMPILER_H
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
#pragma warning(disable : 4514) // unreferenced inline function has been removed
|
#pragma warning(disable : 4514) // unreferenced inline function has been removed
|
||||||
#pragma warning(disable : 4702) // unreachable code
|
#pragma warning(disable : 4702) // unreachable code
|
||||||
#pragma warning(disable : 4710) // not inlined
|
#pragma warning(disable : 4710) // not inlined
|
||||||
|
#pragma warning(disable : 4714) // function marked as __forceinline not inlined
|
||||||
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
|
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
175
C/CpuArch.h
175
C/CpuArch.h
@@ -1,5 +1,5 @@
|
|||||||
/* CpuArch.h -- CPU specific code
|
/* CpuArch.h -- CPU specific code
|
||||||
2015-12-01: Igor Pavlov : Public domain */
|
2017-06-30 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __CPU_ARCH_H
|
#ifndef __CPU_ARCH_H
|
||||||
#define __CPU_ARCH_H
|
#define __CPU_ARCH_H
|
||||||
@@ -16,48 +16,122 @@ If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of pl
|
|||||||
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
|
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(_M_X64) \
|
#if defined(_M_X64) \
|
||||||
|| defined(_M_AMD64) \
|
|| defined(_M_AMD64) \
|
||||||
|| defined(__x86_64__) \
|
|| defined(__x86_64__) \
|
||||||
|| defined(__AMD64__) \
|
|| defined(__AMD64__) \
|
||||||
|| defined(__amd64__)
|
|| defined(__amd64__)
|
||||||
#define MY_CPU_AMD64
|
#define MY_CPU_AMD64
|
||||||
#endif
|
#ifdef __ILP32__
|
||||||
|
#define MY_CPU_NAME "x32"
|
||||||
#if defined(MY_CPU_AMD64) \
|
#else
|
||||||
|| defined(_M_IA64) \
|
#define MY_CPU_NAME "x64"
|
||||||
|| defined(__AARCH64EL__) \
|
#endif
|
||||||
|| defined(__AARCH64EB__)
|
|
||||||
#define MY_CPU_64BIT
|
#define MY_CPU_64BIT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_M_IX86) || defined(__i386__)
|
|
||||||
#define MY_CPU_X86
|
#if defined(_M_IX86) \
|
||||||
|
|| defined(__i386__)
|
||||||
|
#define MY_CPU_X86
|
||||||
|
#define MY_CPU_NAME "x86"
|
||||||
|
#define MY_CPU_32BIT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_M_ARM64) \
|
||||||
|
|| defined(__AARCH64EL__) \
|
||||||
|
|| defined(__AARCH64EB__) \
|
||||||
|
|| defined(__aarch64__)
|
||||||
|
#define MY_CPU_ARM64
|
||||||
|
#define MY_CPU_NAME "arm64"
|
||||||
|
#define MY_CPU_64BIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_M_ARM) \
|
||||||
|
|| defined(_M_ARM_NT) \
|
||||||
|
|| defined(_M_ARMT) \
|
||||||
|
|| defined(__arm__) \
|
||||||
|
|| defined(__thumb__) \
|
||||||
|
|| defined(__ARMEL__) \
|
||||||
|
|| defined(__ARMEB__) \
|
||||||
|
|| defined(__THUMBEL__) \
|
||||||
|
|| defined(__THUMBEB__)
|
||||||
|
#define MY_CPU_ARM
|
||||||
|
#define MY_CPU_NAME "arm"
|
||||||
|
#define MY_CPU_32BIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_M_IA64) \
|
||||||
|
|| defined(__ia64__)
|
||||||
|
#define MY_CPU_IA64
|
||||||
|
#define MY_CPU_NAME "ia64"
|
||||||
|
#define MY_CPU_64BIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__mips64) \
|
||||||
|
|| defined(__mips64__) \
|
||||||
|
|| (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
|
||||||
|
#define MY_CPU_NAME "mips64"
|
||||||
|
#define MY_CPU_64BIT
|
||||||
|
#elif defined(__mips__)
|
||||||
|
#define MY_CPU_NAME "mips"
|
||||||
|
/* #define MY_CPU_32BIT */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__ppc64__) \
|
||||||
|
|| defined(__powerpc64__)
|
||||||
|
#ifdef __ILP32__
|
||||||
|
#define MY_CPU_NAME "ppc64-32"
|
||||||
|
#else
|
||||||
|
#define MY_CPU_NAME "ppc64"
|
||||||
|
#endif
|
||||||
|
#define MY_CPU_64BIT
|
||||||
|
#elif defined(__ppc__) \
|
||||||
|
|| defined(__powerpc__)
|
||||||
|
#define MY_CPU_NAME "ppc"
|
||||||
|
#define MY_CPU_32BIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__sparc64__)
|
||||||
|
#define MY_CPU_NAME "sparc64"
|
||||||
|
#define MY_CPU_64BIT
|
||||||
|
#elif defined(__sparc__)
|
||||||
|
#define MY_CPU_NAME "sparc"
|
||||||
|
/* #define MY_CPU_32BIT */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
|
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
|
||||||
#define MY_CPU_X86_OR_AMD64
|
#define MY_CPU_X86_OR_AMD64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_X86) \
|
|
||||||
|| defined(_M_ARM) \
|
#ifdef _WIN32
|
||||||
|| defined(__ARMEL__) \
|
|
||||||
|| defined(__THUMBEL__) \
|
#ifdef MY_CPU_ARM
|
||||||
|| defined(__ARMEB__) \
|
#define MY_CPU_ARM_LE
|
||||||
|| defined(__THUMBEB__)
|
#endif
|
||||||
#define MY_CPU_32BIT
|
|
||||||
|
#ifdef MY_CPU_ARM64
|
||||||
|
#define MY_CPU_ARM64_LE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _M_IA64
|
||||||
|
#define MY_CPU_IA64_LE
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(_M_ARM)
|
|
||||||
#define MY_CPU_ARM_LE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(_M_IA64)
|
|
||||||
#define MY_CPU_IA64_LE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MY_CPU_X86_OR_AMD64) \
|
#if defined(MY_CPU_X86_OR_AMD64) \
|
||||||
|| defined(MY_CPU_ARM_LE) \
|
|| defined(MY_CPU_ARM_LE) \
|
||||||
|
|| defined(MY_CPU_ARM64_LE) \
|
||||||
|| defined(MY_CPU_IA64_LE) \
|
|| defined(MY_CPU_IA64_LE) \
|
||||||
|| defined(__LITTLE_ENDIAN__) \
|
|| defined(__LITTLE_ENDIAN__) \
|
||||||
|| defined(__ARMEL__) \
|
|| defined(__ARMEL__) \
|
||||||
@@ -66,6 +140,7 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem
|
|||||||
|| defined(__MIPSEL__) \
|
|| defined(__MIPSEL__) \
|
||||||
|| defined(__MIPSEL) \
|
|| defined(__MIPSEL) \
|
||||||
|| defined(_MIPSEL) \
|
|| defined(_MIPSEL) \
|
||||||
|
|| defined(__BFIN__) \
|
||||||
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
|
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
|
||||||
#define MY_CPU_LE
|
#define MY_CPU_LE
|
||||||
#endif
|
#endif
|
||||||
@@ -85,14 +160,37 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem
|
|||||||
#define MY_CPU_BE
|
#define MY_CPU_BE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
|
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
|
||||||
Stop_Compiling_Bad_Endian
|
#error Stop_Compiling_Bad_Endian
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
|
||||||
|
#error Stop_Compiling_Bad_32_64_BIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MY_CPU_NAME
|
||||||
|
#ifdef MY_CPU_LE
|
||||||
|
#define MY_CPU_NAME "LE"
|
||||||
|
#elif MY_CPU_BE
|
||||||
|
#define MY_CPU_NAME "BE"
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
#define MY_CPU_NAME ""
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef MY_CPU_LE
|
#ifdef MY_CPU_LE
|
||||||
#if defined(MY_CPU_X86_OR_AMD64) \
|
#if defined(MY_CPU_X86_OR_AMD64) \
|
||||||
/* || defined(__AARCH64EL__) */
|
|| defined(MY_CPU_ARM64) \
|
||||||
|
|| defined(__ARM_FEATURE_UNALIGNED)
|
||||||
#define MY_CPU_LE_UNALIGN
|
#define MY_CPU_LE_UNALIGN
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -138,6 +236,11 @@ Stop_Compiling_Bad_Endian
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __has_builtin
|
||||||
|
#define MY__has_builtin(x) __has_builtin(x)
|
||||||
|
#else
|
||||||
|
#define MY__has_builtin(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
|
#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
|
||||||
|
|
||||||
@@ -145,15 +248,21 @@ Stop_Compiling_Bad_Endian
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#pragma intrinsic(_byteswap_ushort)
|
||||||
#pragma intrinsic(_byteswap_ulong)
|
#pragma intrinsic(_byteswap_ulong)
|
||||||
#pragma intrinsic(_byteswap_uint64)
|
#pragma intrinsic(_byteswap_uint64)
|
||||||
|
|
||||||
|
/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */
|
||||||
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
||||||
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
|
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
|
||||||
|
|
||||||
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
|
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
|
||||||
|
|
||||||
#elif defined(MY_CPU_LE_UNALIGN) && defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
|
#elif defined(MY_CPU_LE_UNALIGN) && ( \
|
||||||
|
(defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
|
||||||
|
|| (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) )
|
||||||
|
|
||||||
|
/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */
|
||||||
#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
|
#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
|
||||||
#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
|
#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
|
||||||
|
|
||||||
@@ -178,10 +287,14 @@ Stop_Compiling_Bad_Endian
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef GetBe16
|
||||||
|
|
||||||
#define GetBe16(p) ( (UInt16) ( \
|
#define GetBe16(p) ( (UInt16) ( \
|
||||||
((UInt16)((const Byte *)(p))[0] << 8) | \
|
((UInt16)((const Byte *)(p))[0] << 8) | \
|
||||||
((const Byte *)(p))[1] ))
|
((const Byte *)(p))[1] ))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
|
|||||||
87
C/DllSecur.c
Normal file
87
C/DllSecur.c
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
/* DllSecur.c -- DLL loading security
|
||||||
|
2016-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "Precomp.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include "DllSecur.h"
|
||||||
|
|
||||||
|
#ifndef UNDER_CE
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI *Func_SetDefaultDllDirectories)(DWORD DirectoryFlags);
|
||||||
|
|
||||||
|
#define MY_LOAD_LIBRARY_SEARCH_USER_DIRS 0x400
|
||||||
|
#define MY_LOAD_LIBRARY_SEARCH_SYSTEM32 0x800
|
||||||
|
|
||||||
|
static const char * const g_Dlls =
|
||||||
|
#ifndef _CONSOLE
|
||||||
|
"UXTHEME\0"
|
||||||
|
#endif
|
||||||
|
"USERENV\0"
|
||||||
|
"SETUPAPI\0"
|
||||||
|
"APPHELP\0"
|
||||||
|
"PROPSYS\0"
|
||||||
|
"DWMAPI\0"
|
||||||
|
"CRYPTBASE\0"
|
||||||
|
"OLEACC\0"
|
||||||
|
"CLBCATQ\0"
|
||||||
|
;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void LoadSecurityDlls()
|
||||||
|
{
|
||||||
|
#ifndef UNDER_CE
|
||||||
|
|
||||||
|
wchar_t buf[MAX_PATH + 100];
|
||||||
|
|
||||||
|
{
|
||||||
|
// at Vista (ver 6.0) : CoCreateInstance(CLSID_ShellLink, ...) doesn't work after SetDefaultDllDirectories() : Check it ???
|
||||||
|
OSVERSIONINFO vi;
|
||||||
|
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||||
|
if (!GetVersionEx(&vi) || vi.dwMajorVersion != 6 || vi.dwMinorVersion != 0)
|
||||||
|
{
|
||||||
|
Func_SetDefaultDllDirectories setDllDirs = (Func_SetDefaultDllDirectories)
|
||||||
|
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "SetDefaultDllDirectories");
|
||||||
|
if (setDllDirs)
|
||||||
|
if (setDllDirs(MY_LOAD_LIBRARY_SEARCH_SYSTEM32 | MY_LOAD_LIBRARY_SEARCH_USER_DIRS))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
unsigned len = GetSystemDirectoryW(buf, MAX_PATH + 2);
|
||||||
|
if (len == 0 || len > MAX_PATH)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const char *dll;
|
||||||
|
unsigned pos = (unsigned)lstrlenW(buf);
|
||||||
|
|
||||||
|
if (buf[pos - 1] != '\\')
|
||||||
|
buf[pos++] = '\\';
|
||||||
|
|
||||||
|
for (dll = g_Dlls; dll[0] != 0;)
|
||||||
|
{
|
||||||
|
unsigned k = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
char c = *dll++;
|
||||||
|
buf[pos + k] = c;
|
||||||
|
k++;
|
||||||
|
if (c == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lstrcatW(buf, L".dll");
|
||||||
|
LoadLibraryExW(buf, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
19
C/DllSecur.h
Normal file
19
C/DllSecur.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/* DllSecur.h -- DLL loading for security
|
||||||
|
2016-06-08 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef __DLL_SECUR_H
|
||||||
|
#define __DLL_SECUR_H
|
||||||
|
|
||||||
|
#include "7zTypes.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
void LoadSecurityDlls();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
16
C/HuffEnc.c
16
C/HuffEnc.c
@@ -1,5 +1,5 @@
|
|||||||
/* HuffEnc.c -- functions for Huffman encoding
|
/* HuffEnc.c -- functions for Huffman encoding
|
||||||
2009-09-02 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
|
|||||||
if (len >= maxLen)
|
if (len >= maxLen)
|
||||||
for (len = maxLen - 1; lenCounters[len] == 0; len--);
|
for (len = maxLen - 1; lenCounters[len] == 0; len--);
|
||||||
lenCounters[len]--;
|
lenCounters[len]--;
|
||||||
lenCounters[len + 1] += 2;
|
lenCounters[(size_t)len + 1] += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -121,8 +121,8 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
|
|||||||
i = 0;
|
i = 0;
|
||||||
for (len = maxLen; len != 0; len--)
|
for (len = maxLen; len != 0; len--)
|
||||||
{
|
{
|
||||||
UInt32 num;
|
UInt32 k;
|
||||||
for (num = lenCounters[len]; num != 0; num--)
|
for (k = lenCounters[len]; k != 0; k--)
|
||||||
lens[p[i++] & MASK] = (Byte)len;
|
lens[p[i++] & MASK] = (Byte)len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,14 +133,14 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
|
|||||||
UInt32 code = 0;
|
UInt32 code = 0;
|
||||||
UInt32 len;
|
UInt32 len;
|
||||||
for (len = 1; len <= kMaxLen; len++)
|
for (len = 1; len <= kMaxLen; len++)
|
||||||
nextCodes[len] = code = (code + lenCounters[len - 1]) << 1;
|
nextCodes[len] = code = (code + lenCounters[(size_t)len - 1]) << 1;
|
||||||
}
|
}
|
||||||
/* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */
|
/* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */
|
||||||
|
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 k;
|
||||||
for (i = 0; i < numSymbols; i++)
|
for (k = 0; k < numSymbols; k++)
|
||||||
p[i] = nextCodes[lens[i]]++;
|
p[k] = nextCodes[lens[k]]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
163
C/LzFind.c
163
C/LzFind.c
@@ -1,5 +1,5 @@
|
|||||||
/* LzFind.c -- Match finder for LZ algorithms
|
/* LzFind.c -- Match finder for LZ algorithms
|
||||||
2015-10-15 : Igor Pavlov : Public domain */
|
2017-06-10 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -16,18 +16,18 @@
|
|||||||
|
|
||||||
#define kStartMaxLen 3
|
#define kStartMaxLen 3
|
||||||
|
|
||||||
static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
|
static void LzInWindow_Free(CMatchFinder *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
if (!p->directInput)
|
if (!p->directInput)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->bufferBase);
|
ISzAlloc_Free(alloc, p->bufferBase);
|
||||||
p->bufferBase = NULL;
|
p->bufferBase = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
|
/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
|
||||||
|
|
||||||
static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
|
static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
|
UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
|
||||||
if (p->directInput)
|
if (p->directInput)
|
||||||
@@ -39,7 +39,7 @@ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *a
|
|||||||
{
|
{
|
||||||
LzInWindow_Free(p, alloc);
|
LzInWindow_Free(p, alloc);
|
||||||
p->blockSize = blockSize;
|
p->blockSize = blockSize;
|
||||||
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
|
p->bufferBase = (Byte *)ISzAlloc_Alloc(alloc, (size_t)blockSize);
|
||||||
}
|
}
|
||||||
return (p->bufferBase != NULL);
|
return (p->bufferBase != NULL);
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
|
|||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p->result = p->stream->Read(p->stream, dest, &size);
|
p->result = ISeqInStream_Read(p->stream, dest, &size);
|
||||||
if (p->result != SZ_OK)
|
if (p->result != SZ_OK)
|
||||||
return;
|
return;
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
@@ -142,6 +142,7 @@ void MatchFinder_Construct(CMatchFinder *p)
|
|||||||
p->bufferBase = NULL;
|
p->bufferBase = NULL;
|
||||||
p->directInput = 0;
|
p->directInput = 0;
|
||||||
p->hash = NULL;
|
p->hash = NULL;
|
||||||
|
p->expectedDataSize = (UInt64)(Int64)-1;
|
||||||
MatchFinder_SetDefaultSettings(p);
|
MatchFinder_SetDefaultSettings(p);
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
@@ -149,34 +150,34 @@ void MatchFinder_Construct(CMatchFinder *p)
|
|||||||
UInt32 r = i;
|
UInt32 r = i;
|
||||||
unsigned j;
|
unsigned j;
|
||||||
for (j = 0; j < 8; j++)
|
for (j = 0; j < 8; j++)
|
||||||
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
|
||||||
p->crc[i] = r;
|
p->crc[i] = r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
|
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->hash);
|
ISzAlloc_Free(alloc, p->hash);
|
||||||
p->hash = NULL;
|
p->hash = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
|
void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
MatchFinder_FreeThisClassMemory(p, alloc);
|
MatchFinder_FreeThisClassMemory(p, alloc);
|
||||||
LzInWindow_Free(p, alloc);
|
LzInWindow_Free(p, alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CLzRef* AllocRefs(size_t num, ISzAlloc *alloc)
|
static CLzRef* AllocRefs(size_t num, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
|
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
|
||||||
if (sizeInBytes / sizeof(CLzRef) != num)
|
if (sizeInBytes / sizeof(CLzRef) != num)
|
||||||
return NULL;
|
return NULL;
|
||||||
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
|
return (CLzRef *)ISzAlloc_Alloc(alloc, sizeInBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||||
ISzAlloc *alloc)
|
ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
UInt32 sizeReserv;
|
UInt32 sizeReserv;
|
||||||
|
|
||||||
@@ -208,7 +209,11 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
|||||||
hs = (1 << 16) - 1;
|
hs = (1 << 16) - 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hs = historySize - 1;
|
hs = historySize;
|
||||||
|
if (hs > p->expectedDataSize)
|
||||||
|
hs = (UInt32)p->expectedDataSize;
|
||||||
|
if (hs != 0)
|
||||||
|
hs--;
|
||||||
hs |= (hs >> 1);
|
hs |= (hs >> 1);
|
||||||
hs |= (hs >> 2);
|
hs |= (hs >> 2);
|
||||||
hs |= (hs >> 4);
|
hs |= (hs >> 4);
|
||||||
@@ -292,17 +297,33 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
|
|||||||
p->posLimit = p->pos + limit;
|
p->posLimit = p->pos + limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinder_Init_2(CMatchFinder *p, int readData)
|
|
||||||
|
void MatchFinder_Init_LowHash(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
CLzRef *items = p->hash;
|
||||||
|
size_t numItems = p->fixedHashSize;
|
||||||
|
for (i = 0; i < numItems; i++)
|
||||||
|
items[i] = kEmptyHashValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MatchFinder_Init_HighHash(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
CLzRef *items = p->hash + p->fixedHashSize;
|
||||||
|
size_t numItems = (size_t)p->hashMask + 1;
|
||||||
|
for (i = 0; i < numItems; i++)
|
||||||
|
items[i] = kEmptyHashValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MatchFinder_Init_3(CMatchFinder *p, int readData)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
|
||||||
UInt32 *hash = p->hash;
|
|
||||||
UInt32 num = p->hashSizeSum;
|
|
||||||
for (i = 0; i < num; i++)
|
|
||||||
hash[i] = kEmptyHashValue;
|
|
||||||
|
|
||||||
p->cyclicBufferPos = 0;
|
p->cyclicBufferPos = 0;
|
||||||
p->buffer = p->bufferBase;
|
p->buffer = p->bufferBase;
|
||||||
p->pos = p->streamPos = p->cyclicBufferSize;
|
p->pos =
|
||||||
|
p->streamPos = p->cyclicBufferSize;
|
||||||
p->result = SZ_OK;
|
p->result = SZ_OK;
|
||||||
p->streamEndWasReached = 0;
|
p->streamEndWasReached = 0;
|
||||||
|
|
||||||
@@ -312,10 +333,14 @@ void MatchFinder_Init_2(CMatchFinder *p, int readData)
|
|||||||
MatchFinder_SetLimits(p);
|
MatchFinder_SetLimits(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MatchFinder_Init(CMatchFinder *p)
|
void MatchFinder_Init(CMatchFinder *p)
|
||||||
{
|
{
|
||||||
MatchFinder_Init_2(p, True);
|
MatchFinder_Init_HighHash(p);
|
||||||
|
MatchFinder_Init_LowHash(p);
|
||||||
|
MatchFinder_Init_3(p, True);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
|
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
|
||||||
{
|
{
|
||||||
@@ -558,10 +583,10 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
|
|
||||||
d2 = pos - hash[h2];
|
d2 = pos - hash[h2];
|
||||||
|
|
||||||
curMatch = hash[kFix3HashSize + hv];
|
curMatch = (hash + kFix3HashSize)[hv];
|
||||||
|
|
||||||
hash[h2] = pos;
|
hash[h2] = pos;
|
||||||
hash[kFix3HashSize + hv] = pos;
|
(hash + kFix3HashSize)[hv] = pos;
|
||||||
|
|
||||||
maxLen = 2;
|
maxLen = 2;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
@@ -594,13 +619,13 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
pos = p->pos;
|
pos = p->pos;
|
||||||
|
|
||||||
d2 = pos - hash[ h2];
|
d2 = pos - hash[ h2];
|
||||||
d3 = pos - hash[kFix3HashSize + h3];
|
d3 = pos - (hash + kFix3HashSize)[h3];
|
||||||
|
|
||||||
curMatch = hash[kFix4HashSize + hv];
|
curMatch = (hash + kFix4HashSize)[hv];
|
||||||
|
|
||||||
hash[ h2] = pos;
|
hash[ h2] = pos;
|
||||||
hash[kFix3HashSize + h3] = pos;
|
(hash + kFix3HashSize)[h3] = pos;
|
||||||
hash[kFix4HashSize + hv] = pos;
|
(hash + kFix4HashSize)[hv] = pos;
|
||||||
|
|
||||||
maxLen = 0;
|
maxLen = 0;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
@@ -615,7 +640,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
|
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
|
||||||
{
|
{
|
||||||
maxLen = 3;
|
maxLen = 3;
|
||||||
distances[offset + 1] = d3 - 1;
|
distances[(size_t)offset + 1] = d3 - 1;
|
||||||
offset += 2;
|
offset += 2;
|
||||||
d2 = d3;
|
d2 = d3;
|
||||||
}
|
}
|
||||||
@@ -623,7 +648,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
if (offset != 0)
|
if (offset != 0)
|
||||||
{
|
{
|
||||||
UPDATE_maxLen
|
UPDATE_maxLen
|
||||||
distances[offset - 2] = maxLen;
|
distances[(size_t)offset - 2] = maxLen;
|
||||||
if (maxLen == lenLimit)
|
if (maxLen == lenLimit)
|
||||||
{
|
{
|
||||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
||||||
@@ -650,15 +675,15 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
pos = p->pos;
|
pos = p->pos;
|
||||||
|
|
||||||
d2 = pos - hash[ h2];
|
d2 = pos - hash[ h2];
|
||||||
d3 = pos - hash[kFix3HashSize + h3];
|
d3 = pos - (hash + kFix3HashSize)[h3];
|
||||||
d4 = pos - hash[kFix4HashSize + h4];
|
d4 = pos - (hash + kFix4HashSize)[h4];
|
||||||
|
|
||||||
curMatch = hash[kFix5HashSize + hv];
|
curMatch = (hash + kFix5HashSize)[hv];
|
||||||
|
|
||||||
hash[ h2] = pos;
|
hash[ h2] = pos;
|
||||||
hash[kFix3HashSize + h3] = pos;
|
(hash + kFix3HashSize)[h3] = pos;
|
||||||
hash[kFix4HashSize + h4] = pos;
|
(hash + kFix4HashSize)[h4] = pos;
|
||||||
hash[kFix5HashSize + hv] = pos;
|
(hash + kFix5HashSize)[hv] = pos;
|
||||||
|
|
||||||
maxLen = 0;
|
maxLen = 0;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
@@ -691,7 +716,7 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
&& *(cur - d4 + 3) == *(cur + 3))
|
&& *(cur - d4 + 3) == *(cur + 3))
|
||||||
{
|
{
|
||||||
maxLen = 4;
|
maxLen = 4;
|
||||||
distances[offset + 1] = d4 - 1;
|
distances[(size_t)offset + 1] = d4 - 1;
|
||||||
offset += 2;
|
offset += 2;
|
||||||
d2 = d4;
|
d2 = d4;
|
||||||
}
|
}
|
||||||
@@ -699,7 +724,7 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
if (offset != 0)
|
if (offset != 0)
|
||||||
{
|
{
|
||||||
UPDATE_maxLen
|
UPDATE_maxLen
|
||||||
distances[offset - 2] = maxLen;
|
distances[(size_t)offset - 2] = maxLen;
|
||||||
if (maxLen == lenLimit)
|
if (maxLen == lenLimit)
|
||||||
{
|
{
|
||||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
||||||
@@ -726,13 +751,13 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
pos = p->pos;
|
pos = p->pos;
|
||||||
|
|
||||||
d2 = pos - hash[ h2];
|
d2 = pos - hash[ h2];
|
||||||
d3 = pos - hash[kFix3HashSize + h3];
|
d3 = pos - (hash + kFix3HashSize)[h3];
|
||||||
|
|
||||||
curMatch = hash[kFix4HashSize + hv];
|
curMatch = (hash + kFix4HashSize)[hv];
|
||||||
|
|
||||||
hash[ h2] = pos;
|
hash[ h2] = pos;
|
||||||
hash[kFix3HashSize + h3] = pos;
|
(hash + kFix3HashSize)[h3] = pos;
|
||||||
hash[kFix4HashSize + hv] = pos;
|
(hash + kFix4HashSize)[hv] = pos;
|
||||||
|
|
||||||
maxLen = 0;
|
maxLen = 0;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
@@ -747,7 +772,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
|
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
|
||||||
{
|
{
|
||||||
maxLen = 3;
|
maxLen = 3;
|
||||||
distances[offset + 1] = d3 - 1;
|
distances[(size_t)offset + 1] = d3 - 1;
|
||||||
offset += 2;
|
offset += 2;
|
||||||
d2 = d3;
|
d2 = d3;
|
||||||
}
|
}
|
||||||
@@ -755,7 +780,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
if (offset != 0)
|
if (offset != 0)
|
||||||
{
|
{
|
||||||
UPDATE_maxLen
|
UPDATE_maxLen
|
||||||
distances[offset - 2] = maxLen;
|
distances[(size_t)offset - 2] = maxLen;
|
||||||
if (maxLen == lenLimit)
|
if (maxLen == lenLimit)
|
||||||
{
|
{
|
||||||
p->son[p->cyclicBufferPos] = curMatch;
|
p->son[p->cyclicBufferPos] = curMatch;
|
||||||
@@ -784,15 +809,15 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
pos = p->pos;
|
pos = p->pos;
|
||||||
|
|
||||||
d2 = pos - hash[ h2];
|
d2 = pos - hash[ h2];
|
||||||
d3 = pos - hash[kFix3HashSize + h3];
|
d3 = pos - (hash + kFix3HashSize)[h3];
|
||||||
d4 = pos - hash[kFix4HashSize + h4];
|
d4 = pos - (hash + kFix4HashSize)[h4];
|
||||||
|
|
||||||
curMatch = hash[kFix5HashSize + hv];
|
curMatch = (hash + kFix5HashSize)[hv];
|
||||||
|
|
||||||
hash[ h2] = pos;
|
hash[ h2] = pos;
|
||||||
hash[kFix3HashSize + h3] = pos;
|
(hash + kFix3HashSize)[h3] = pos;
|
||||||
hash[kFix4HashSize + h4] = pos;
|
(hash + kFix4HashSize)[h4] = pos;
|
||||||
hash[kFix5HashSize + hv] = pos;
|
(hash + kFix5HashSize)[hv] = pos;
|
||||||
|
|
||||||
maxLen = 0;
|
maxLen = 0;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
@@ -825,7 +850,7 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
&& *(cur - d4 + 3) == *(cur + 3))
|
&& *(cur - d4 + 3) == *(cur + 3))
|
||||||
{
|
{
|
||||||
maxLen = 4;
|
maxLen = 4;
|
||||||
distances[offset + 1] = d4 - 1;
|
distances[(size_t)offset + 1] = d4 - 1;
|
||||||
offset += 2;
|
offset += 2;
|
||||||
d2 = d4;
|
d2 = d4;
|
||||||
}
|
}
|
||||||
@@ -833,7 +858,7 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
if (offset != 0)
|
if (offset != 0)
|
||||||
{
|
{
|
||||||
UPDATE_maxLen
|
UPDATE_maxLen
|
||||||
distances[offset - 2] = maxLen;
|
distances[(size_t)offset - 2] = maxLen;
|
||||||
if (maxLen == lenLimit)
|
if (maxLen == lenLimit)
|
||||||
{
|
{
|
||||||
p->son[p->cyclicBufferPos] = curMatch;
|
p->son[p->cyclicBufferPos] = curMatch;
|
||||||
@@ -897,9 +922,9 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
|||||||
SKIP_HEADER(3)
|
SKIP_HEADER(3)
|
||||||
HASH3_CALC;
|
HASH3_CALC;
|
||||||
hash = p->hash;
|
hash = p->hash;
|
||||||
curMatch = hash[kFix3HashSize + hv];
|
curMatch = (hash + kFix3HashSize)[hv];
|
||||||
hash[h2] =
|
hash[h2] =
|
||||||
hash[kFix3HashSize + hv] = p->pos;
|
(hash + kFix3HashSize)[hv] = p->pos;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER
|
||||||
}
|
}
|
||||||
while (--num != 0);
|
while (--num != 0);
|
||||||
@@ -914,10 +939,10 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
|||||||
SKIP_HEADER(4)
|
SKIP_HEADER(4)
|
||||||
HASH4_CALC;
|
HASH4_CALC;
|
||||||
hash = p->hash;
|
hash = p->hash;
|
||||||
curMatch = hash[kFix4HashSize + hv];
|
curMatch = (hash + kFix4HashSize)[hv];
|
||||||
hash[ h2] =
|
hash[ h2] =
|
||||||
hash[kFix3HashSize + h3] =
|
(hash + kFix3HashSize)[h3] =
|
||||||
hash[kFix4HashSize + hv] = p->pos;
|
(hash + kFix4HashSize)[hv] = p->pos;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER
|
||||||
}
|
}
|
||||||
while (--num != 0);
|
while (--num != 0);
|
||||||
@@ -933,11 +958,11 @@ static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
|||||||
SKIP_HEADER(5)
|
SKIP_HEADER(5)
|
||||||
HASH5_CALC;
|
HASH5_CALC;
|
||||||
hash = p->hash;
|
hash = p->hash;
|
||||||
curMatch = hash[kFix5HashSize + hv];
|
curMatch = (hash + kFix5HashSize)[hv];
|
||||||
hash[ h2] =
|
hash[ h2] =
|
||||||
hash[kFix3HashSize + h3] =
|
(hash + kFix3HashSize)[h3] =
|
||||||
hash[kFix4HashSize + h4] =
|
(hash + kFix4HashSize)[h4] =
|
||||||
hash[kFix5HashSize + hv] = p->pos;
|
(hash + kFix5HashSize)[hv] = p->pos;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER
|
||||||
}
|
}
|
||||||
while (--num != 0);
|
while (--num != 0);
|
||||||
@@ -953,10 +978,10 @@ static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
|||||||
SKIP_HEADER(4)
|
SKIP_HEADER(4)
|
||||||
HASH4_CALC;
|
HASH4_CALC;
|
||||||
hash = p->hash;
|
hash = p->hash;
|
||||||
curMatch = hash[kFix4HashSize + hv];
|
curMatch = (hash + kFix4HashSize)[hv];
|
||||||
hash[ h2] =
|
hash[ h2] =
|
||||||
hash[kFix3HashSize + h3] =
|
(hash + kFix3HashSize)[h3] =
|
||||||
hash[kFix4HashSize + hv] = p->pos;
|
(hash + kFix4HashSize)[hv] = p->pos;
|
||||||
p->son[p->cyclicBufferPos] = curMatch;
|
p->son[p->cyclicBufferPos] = curMatch;
|
||||||
MOVE_POS
|
MOVE_POS
|
||||||
}
|
}
|
||||||
@@ -973,11 +998,11 @@ static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
|||||||
SKIP_HEADER(5)
|
SKIP_HEADER(5)
|
||||||
HASH5_CALC;
|
HASH5_CALC;
|
||||||
hash = p->hash;
|
hash = p->hash;
|
||||||
curMatch = p->hash[kFix5HashSize + hv];
|
curMatch = hash + kFix5HashSize)[hv];
|
||||||
hash[ h2] =
|
hash[ h2] =
|
||||||
hash[kFix3HashSize + h3] =
|
(hash + kFix3HashSize)[h3] =
|
||||||
hash[kFix4HashSize + h4] =
|
(hash + kFix4HashSize)[h4] =
|
||||||
hash[kFix5HashSize + hv] = p->pos;
|
(hash + kFix5HashSize)[hv] = p->pos;
|
||||||
p->son[p->cyclicBufferPos] = curMatch;
|
p->son[p->cyclicBufferPos] = curMatch;
|
||||||
MOVE_POS
|
MOVE_POS
|
||||||
}
|
}
|
||||||
|
|||||||
12
C/LzFind.h
12
C/LzFind.h
@@ -1,5 +1,5 @@
|
|||||||
/* LzFind.h -- Match finder for LZ algorithms
|
/* LzFind.h -- Match finder for LZ algorithms
|
||||||
2015-10-15 : Igor Pavlov : Public domain */
|
2017-06-10 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZ_FIND_H
|
#ifndef __LZ_FIND_H
|
||||||
#define __LZ_FIND_H
|
#define __LZ_FIND_H
|
||||||
@@ -47,6 +47,8 @@ typedef struct _CMatchFinder
|
|||||||
SRes result;
|
SRes result;
|
||||||
UInt32 crc[256];
|
UInt32 crc[256];
|
||||||
size_t numRefs;
|
size_t numRefs;
|
||||||
|
|
||||||
|
UInt64 expectedDataSize;
|
||||||
} CMatchFinder;
|
} CMatchFinder;
|
||||||
|
|
||||||
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
|
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
|
||||||
@@ -71,8 +73,8 @@ void MatchFinder_Construct(CMatchFinder *p);
|
|||||||
*/
|
*/
|
||||||
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||||
ISzAlloc *alloc);
|
ISzAllocPtr alloc);
|
||||||
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
|
void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc);
|
||||||
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
|
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
|
||||||
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
|
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
|
||||||
|
|
||||||
@@ -103,7 +105,9 @@ typedef struct _IMatchFinder
|
|||||||
|
|
||||||
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
|
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
|
||||||
|
|
||||||
void MatchFinder_Init_2(CMatchFinder *p, int readData);
|
void MatchFinder_Init_LowHash(CMatchFinder *p);
|
||||||
|
void MatchFinder_Init_HighHash(CMatchFinder *p);
|
||||||
|
void MatchFinder_Init_3(CMatchFinder *p, int readData);
|
||||||
void MatchFinder_Init(CMatchFinder *p);
|
void MatchFinder_Init(CMatchFinder *p);
|
||||||
|
|
||||||
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||||
|
|||||||
67
C/LzFindMt.c
67
C/LzFindMt.c
@@ -1,5 +1,5 @@
|
|||||||
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
|
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
|
||||||
2015-10-15 : Igor Pavlov : Public domain */
|
2017-06-10 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -33,6 +33,8 @@ static void MtSync_GetNextBlock(CMtSync *p)
|
|||||||
|
|
||||||
Event_Set(&p->canStart);
|
Event_Set(&p->canStart);
|
||||||
Event_Wait(&p->wasStarted);
|
Event_Wait(&p->wasStarted);
|
||||||
|
|
||||||
|
// if (mt) MatchFinder_Init_LowHash(mt->MatchFinder);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -155,6 +157,9 @@ static void HashThreadFunc(CMatchFinderMt *mt)
|
|||||||
UInt32 numProcessedBlocks = 0;
|
UInt32 numProcessedBlocks = 0;
|
||||||
Event_Wait(&p->canStart);
|
Event_Wait(&p->canStart);
|
||||||
Event_Set(&p->wasStarted);
|
Event_Set(&p->wasStarted);
|
||||||
|
|
||||||
|
MatchFinder_Init_HighHash(mt->MatchFinder);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (p->exit)
|
if (p->exit)
|
||||||
@@ -205,7 +210,7 @@ static void HashThreadFunc(CMatchFinderMt *mt)
|
|||||||
if (num > kMtHashBlockSize - 2)
|
if (num > kMtHashBlockSize - 2)
|
||||||
num = kMtHashBlockSize - 2;
|
num = kMtHashBlockSize - 2;
|
||||||
mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc);
|
mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc);
|
||||||
heads[0] += num;
|
heads[0] = 2 + num;
|
||||||
}
|
}
|
||||||
mf->pos += num;
|
mf->pos += num;
|
||||||
mf->buffer += num;
|
mf->buffer += num;
|
||||||
@@ -443,13 +448,13 @@ void MatchFinderMt_Construct(CMatchFinderMt *p)
|
|||||||
MtSync_Construct(&p->btSync);
|
MtSync_Construct(&p->btSync);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
|
static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->hashBuf);
|
ISzAlloc_Free(alloc, p->hashBuf);
|
||||||
p->hashBuf = NULL;
|
p->hashBuf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
|
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
MtSync_Destruct(&p->hashSync);
|
MtSync_Destruct(&p->hashSync);
|
||||||
MtSync_Destruct(&p->btSync);
|
MtSync_Destruct(&p->btSync);
|
||||||
@@ -472,7 +477,7 @@ static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
|
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc)
|
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
CMatchFinder *mf = p->MatchFinder;
|
CMatchFinder *mf = p->MatchFinder;
|
||||||
p->historySize = historySize;
|
p->historySize = historySize;
|
||||||
@@ -480,7 +485,7 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
|
|||||||
return SZ_ERROR_PARAM;
|
return SZ_ERROR_PARAM;
|
||||||
if (!p->hashBuf)
|
if (!p->hashBuf)
|
||||||
{
|
{
|
||||||
p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
|
p->hashBuf = (UInt32 *)ISzAlloc_Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
|
||||||
if (!p->hashBuf)
|
if (!p->hashBuf)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
p->btBuf = p->hashBuf + kHashBufferSize;
|
p->btBuf = p->hashBuf + kHashBufferSize;
|
||||||
@@ -496,14 +501,18 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Call it after ReleaseStream / SetStream */
|
/* Call it after ReleaseStream / SetStream */
|
||||||
void MatchFinderMt_Init(CMatchFinderMt *p)
|
static void MatchFinderMt_Init(CMatchFinderMt *p)
|
||||||
{
|
{
|
||||||
CMatchFinder *mf = p->MatchFinder;
|
CMatchFinder *mf = p->MatchFinder;
|
||||||
p->btBufPos = p->btBufPosLimit = 0;
|
|
||||||
p->hashBufPos = p->hashBufPosLimit = 0;
|
p->btBufPos =
|
||||||
|
p->btBufPosLimit = 0;
|
||||||
|
p->hashBufPos =
|
||||||
|
p->hashBufPosLimit = 0;
|
||||||
|
|
||||||
/* Init without data reading. We don't want to read data in this thread */
|
/* Init without data reading. We don't want to read data in this thread */
|
||||||
MatchFinder_Init_2(mf, False);
|
MatchFinder_Init_3(mf, False);
|
||||||
|
MatchFinder_Init_LowHash(mf);
|
||||||
|
|
||||||
p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf);
|
p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf);
|
||||||
p->btNumAvailBytes = 0;
|
p->btNumAvailBytes = 0;
|
||||||
@@ -591,10 +600,10 @@ static UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *dista
|
|||||||
MT_HASH3_CALC
|
MT_HASH3_CALC
|
||||||
|
|
||||||
curMatch2 = hash[ h2];
|
curMatch2 = hash[ h2];
|
||||||
curMatch3 = hash[kFix3HashSize + h3];
|
curMatch3 = (hash + kFix3HashSize)[h3];
|
||||||
|
|
||||||
hash[ h2] = lzPos;
|
hash[ h2] = lzPos;
|
||||||
hash[kFix3HashSize + h3] = lzPos;
|
(hash + kFix3HashSize)[h3] = lzPos;
|
||||||
|
|
||||||
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||||
{
|
{
|
||||||
@@ -627,12 +636,12 @@ static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distan
|
|||||||
MT_HASH4_CALC
|
MT_HASH4_CALC
|
||||||
|
|
||||||
curMatch2 = hash[ h2];
|
curMatch2 = hash[ h2];
|
||||||
curMatch3 = hash[kFix3HashSize + h3];
|
curMatch3 = (hash + kFix3HashSize)[h3];
|
||||||
curMatch4 = hash[kFix4HashSize + h4];
|
curMatch4 = (hash + kFix4HashSize)[h4];
|
||||||
|
|
||||||
hash[ h2] = lzPos;
|
hash[ h2] = lzPos;
|
||||||
hash[kFix3HashSize + h3] = lzPos;
|
(hash + kFix3HashSize)[h3] = lzPos;
|
||||||
hash[kFix4HashSize + h4] = lzPos;
|
(hash + kFix4HashSize)[h4] = lzPos;
|
||||||
|
|
||||||
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||||
{
|
{
|
||||||
@@ -684,8 +693,12 @@ static UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
|||||||
UInt32 i;
|
UInt32 i;
|
||||||
for (i = 0; i < len; i += 2)
|
for (i = 0; i < len; i += 2)
|
||||||
{
|
{
|
||||||
*distances++ = *btBuf++;
|
UInt32 v0 = btBuf[0];
|
||||||
*distances++ = *btBuf++;
|
UInt32 v1 = btBuf[1];
|
||||||
|
btBuf += 2;
|
||||||
|
distances[0] = v0;
|
||||||
|
distances[1] = v1;
|
||||||
|
distances += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
INCREASE_LZ_POS
|
INCREASE_LZ_POS
|
||||||
@@ -712,8 +725,12 @@ static UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
|||||||
distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);
|
distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
*distances2++ = *btBuf++;
|
UInt32 v0 = btBuf[0];
|
||||||
*distances2++ = *btBuf++;
|
UInt32 v1 = btBuf[1];
|
||||||
|
btBuf += 2;
|
||||||
|
distances2[0] = v0;
|
||||||
|
distances2[1] = v1;
|
||||||
|
distances2 += 2;
|
||||||
}
|
}
|
||||||
while ((len -= 2) != 0);
|
while ((len -= 2) != 0);
|
||||||
len = (UInt32)(distances2 - (distances));
|
len = (UInt32)(distances2 - (distances));
|
||||||
@@ -746,7 +763,7 @@ static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
|
|||||||
SKIP_HEADER_MT(3)
|
SKIP_HEADER_MT(3)
|
||||||
UInt32 h2, h3;
|
UInt32 h2, h3;
|
||||||
MT_HASH3_CALC
|
MT_HASH3_CALC
|
||||||
hash[kFix3HashSize + h3] =
|
(hash + kFix3HashSize)[h3] =
|
||||||
hash[ h2] =
|
hash[ h2] =
|
||||||
p->lzPos;
|
p->lzPos;
|
||||||
SKIP_FOOTER_MT
|
SKIP_FOOTER_MT
|
||||||
@@ -758,8 +775,8 @@ static void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
|
|||||||
SKIP_HEADER_MT(4)
|
SKIP_HEADER_MT(4)
|
||||||
UInt32 h2, h3, h4;
|
UInt32 h2, h3, h4;
|
||||||
MT_HASH4_CALC
|
MT_HASH4_CALC
|
||||||
hash[kFix4HashSize + h4] =
|
(hash + kFix4HashSize)[h4] =
|
||||||
hash[kFix3HashSize + h3] =
|
(hash + kFix3HashSize)[h3] =
|
||||||
hash[ h2] =
|
hash[ h2] =
|
||||||
p->lzPos;
|
p->lzPos;
|
||||||
SKIP_FOOTER_MT
|
SKIP_FOOTER_MT
|
||||||
@@ -777,7 +794,7 @@ void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
|
|||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
p->GetHeadsFunc = GetHeads2;
|
p->GetHeadsFunc = GetHeads2;
|
||||||
p->MixMatchesFunc = (Mf_Mix_Matches)0;
|
p->MixMatchesFunc = (Mf_Mix_Matches)NULL;
|
||||||
vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip;
|
vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip;
|
||||||
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches;
|
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
|
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
|
||||||
2015-05-03 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZ_FIND_MT_H
|
#ifndef __LZ_FIND_MT_H
|
||||||
#define __LZ_FIND_MT_H
|
#define __LZ_FIND_MT_H
|
||||||
@@ -90,9 +90,9 @@ typedef struct _CMatchFinderMt
|
|||||||
} CMatchFinderMt;
|
} CMatchFinderMt;
|
||||||
|
|
||||||
void MatchFinderMt_Construct(CMatchFinderMt *p);
|
void MatchFinderMt_Construct(CMatchFinderMt *p);
|
||||||
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc);
|
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc);
|
||||||
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
|
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc);
|
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc);
|
||||||
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
|
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
|
||||||
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
|
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
|
||||||
|
|
||||||
|
|||||||
158
C/Lzma2Dec.c
158
C/Lzma2Dec.c
@@ -1,5 +1,5 @@
|
|||||||
/* Lzma2Dec.c -- LZMA2 Decoder
|
/* Lzma2Dec.c -- LZMA2 Decoder
|
||||||
2015-11-09 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
/* #define SHOW_DEBUG_INFO */
|
/* #define SHOW_DEBUG_INFO */
|
||||||
|
|
||||||
@@ -74,14 +74,14 @@ static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
|
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
Byte props[LZMA_PROPS_SIZE];
|
Byte props[LZMA_PROPS_SIZE];
|
||||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||||
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
|
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
|
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
Byte props[LZMA_PROPS_SIZE];
|
Byte props[LZMA_PROPS_SIZE];
|
||||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||||
@@ -105,16 +105,16 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
|
|||||||
p->control = b;
|
p->control = b;
|
||||||
PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos));
|
PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos));
|
||||||
PRF(printf(" %2X", (unsigned)b));
|
PRF(printf(" %2X", (unsigned)b));
|
||||||
if (p->control == 0)
|
if (b == 0)
|
||||||
return LZMA2_STATE_FINISHED;
|
return LZMA2_STATE_FINISHED;
|
||||||
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
|
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
|
||||||
{
|
{
|
||||||
if ((p->control & 0x7F) > 2)
|
if (b > 2)
|
||||||
return LZMA2_STATE_ERROR;
|
return LZMA2_STATE_ERROR;
|
||||||
p->unpackSize = 0;
|
p->unpackSize = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
|
p->unpackSize = (UInt32)(b & 0x1F) << 16;
|
||||||
return LZMA2_STATE_UNPACK0;
|
return LZMA2_STATE_UNPACK0;
|
||||||
|
|
||||||
case LZMA2_STATE_UNPACK0:
|
case LZMA2_STATE_UNPACK0:
|
||||||
@@ -169,6 +169,7 @@ static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT s
|
|||||||
|
|
||||||
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
|
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
|
||||||
|
|
||||||
|
|
||||||
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
||||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||||
{
|
{
|
||||||
@@ -176,12 +177,17 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
|||||||
*srcLen = 0;
|
*srcLen = 0;
|
||||||
*status = LZMA_STATUS_NOT_SPECIFIED;
|
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||||
|
|
||||||
while (p->state != LZMA2_STATE_FINISHED)
|
while (p->state != LZMA2_STATE_ERROR)
|
||||||
{
|
{
|
||||||
SizeT dicPos = p->decoder.dicPos;
|
SizeT dicPos;
|
||||||
|
|
||||||
|
if (p->state == LZMA2_STATE_FINISHED)
|
||||||
|
{
|
||||||
|
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (p->state == LZMA2_STATE_ERROR)
|
dicPos = p->decoder.dicPos;
|
||||||
return SZ_ERROR_DATA;
|
|
||||||
|
|
||||||
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
|
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
|
||||||
{
|
{
|
||||||
@@ -198,29 +204,25 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
|||||||
}
|
}
|
||||||
(*srcLen)++;
|
(*srcLen)++;
|
||||||
p->state = Lzma2Dec_UpdateState(p, *src++);
|
p->state = Lzma2Dec_UpdateState(p, *src++);
|
||||||
|
|
||||||
if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
|
if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
|
||||||
{
|
break;
|
||||||
p->state = LZMA2_STATE_ERROR;
|
|
||||||
return SZ_ERROR_DATA;
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
SizeT destSizeCur = dicLimit - dicPos;
|
SizeT inCur = inSize - *srcLen;
|
||||||
SizeT srcSizeCur = inSize - *srcLen;
|
SizeT outCur = dicLimit - dicPos;
|
||||||
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
|
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
|
||||||
|
|
||||||
if (p->unpackSize <= destSizeCur)
|
if (outCur >= p->unpackSize)
|
||||||
{
|
{
|
||||||
destSizeCur = (SizeT)p->unpackSize;
|
outCur = (SizeT)p->unpackSize;
|
||||||
curFinishMode = LZMA_FINISH_END;
|
curFinishMode = LZMA_FINISH_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
|
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
|
||||||
{
|
{
|
||||||
if (*srcLen == inSize)
|
if (inCur == 0)
|
||||||
{
|
{
|
||||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
@@ -232,33 +234,25 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
|||||||
if (initDic)
|
if (initDic)
|
||||||
p->needInitProp = p->needInitState = True;
|
p->needInitProp = p->needInitState = True;
|
||||||
else if (p->needInitDic)
|
else if (p->needInitDic)
|
||||||
{
|
break;
|
||||||
p->state = LZMA2_STATE_ERROR;
|
|
||||||
return SZ_ERROR_DATA;
|
|
||||||
}
|
|
||||||
p->needInitDic = False;
|
p->needInitDic = False;
|
||||||
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
|
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srcSizeCur > destSizeCur)
|
if (inCur > outCur)
|
||||||
srcSizeCur = destSizeCur;
|
inCur = outCur;
|
||||||
|
if (inCur == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
if (srcSizeCur == 0)
|
LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur);
|
||||||
{
|
|
||||||
p->state = LZMA2_STATE_ERROR;
|
|
||||||
return SZ_ERROR_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
|
src += inCur;
|
||||||
|
*srcLen += inCur;
|
||||||
src += srcSizeCur;
|
p->unpackSize -= (UInt32)inCur;
|
||||||
*srcLen += srcSizeCur;
|
|
||||||
p->unpackSize -= (UInt32)srcSizeCur;
|
|
||||||
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
|
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SizeT outSizeProcessed;
|
|
||||||
SRes res;
|
SRes res;
|
||||||
|
|
||||||
if (p->state == LZMA2_STATE_DATA)
|
if (p->state == LZMA2_STATE_DATA)
|
||||||
@@ -267,96 +261,98 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
|||||||
Bool initDic = (mode == 3);
|
Bool initDic = (mode == 3);
|
||||||
Bool initState = (mode != 0);
|
Bool initState = (mode != 0);
|
||||||
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
|
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
|
||||||
{
|
break;
|
||||||
p->state = LZMA2_STATE_ERROR;
|
|
||||||
return SZ_ERROR_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
|
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
|
||||||
p->needInitDic = False;
|
p->needInitDic = False;
|
||||||
p->needInitState = False;
|
p->needInitState = False;
|
||||||
p->state = LZMA2_STATE_DATA_CONT;
|
p->state = LZMA2_STATE_DATA_CONT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srcSizeCur > p->packSize)
|
if (inCur > p->packSize)
|
||||||
srcSizeCur = (SizeT)p->packSize;
|
inCur = (SizeT)p->packSize;
|
||||||
|
|
||||||
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
|
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status);
|
||||||
|
|
||||||
src += srcSizeCur;
|
src += inCur;
|
||||||
*srcLen += srcSizeCur;
|
*srcLen += inCur;
|
||||||
p->packSize -= (UInt32)srcSizeCur;
|
p->packSize -= (UInt32)inCur;
|
||||||
|
outCur = p->decoder.dicPos - dicPos;
|
||||||
|
p->unpackSize -= (UInt32)outCur;
|
||||||
|
|
||||||
outSizeProcessed = p->decoder.dicPos - dicPos;
|
if (res != 0)
|
||||||
p->unpackSize -= (UInt32)outSizeProcessed;
|
break;
|
||||||
|
|
||||||
RINOK(res);
|
|
||||||
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||||
return res;
|
{
|
||||||
|
if (p->packSize == 0)
|
||||||
|
break;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (srcSizeCur == 0 && outSizeProcessed == 0)
|
if (inCur == 0 && outCur == 0)
|
||||||
{
|
{
|
||||||
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||||
|| p->unpackSize != 0
|
|| p->unpackSize != 0
|
||||||
|| p->packSize != 0)
|
|| p->packSize != 0)
|
||||||
{
|
break;
|
||||||
p->state = LZMA2_STATE_ERROR;
|
|
||||||
return SZ_ERROR_DATA;
|
|
||||||
}
|
|
||||||
p->state = LZMA2_STATE_CONTROL;
|
p->state = LZMA2_STATE_CONTROL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
|
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||||
*status = LZMA_STATUS_NOT_FINISHED;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||||
return SZ_OK;
|
p->state = LZMA2_STATE_ERROR;
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||||
{
|
{
|
||||||
SizeT outSize = *destLen, inSize = *srcLen;
|
SizeT outSize = *destLen, inSize = *srcLen;
|
||||||
*srcLen = *destLen = 0;
|
*srcLen = *destLen = 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
SizeT srcSizeCur = inSize, outSizeCur, dicPos;
|
SizeT inCur = inSize, outCur, dicPos;
|
||||||
ELzmaFinishMode curFinishMode;
|
ELzmaFinishMode curFinishMode;
|
||||||
SRes res;
|
SRes res;
|
||||||
|
|
||||||
if (p->decoder.dicPos == p->decoder.dicBufSize)
|
if (p->decoder.dicPos == p->decoder.dicBufSize)
|
||||||
p->decoder.dicPos = 0;
|
p->decoder.dicPos = 0;
|
||||||
dicPos = p->decoder.dicPos;
|
dicPos = p->decoder.dicPos;
|
||||||
if (outSize > p->decoder.dicBufSize - dicPos)
|
curFinishMode = LZMA_FINISH_ANY;
|
||||||
|
outCur = p->decoder.dicBufSize - dicPos;
|
||||||
|
|
||||||
|
if (outCur >= outSize)
|
||||||
{
|
{
|
||||||
outSizeCur = p->decoder.dicBufSize;
|
outCur = outSize;
|
||||||
curFinishMode = LZMA_FINISH_ANY;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
outSizeCur = dicPos + outSize;
|
|
||||||
curFinishMode = finishMode;
|
curFinishMode = finishMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
|
res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status);
|
||||||
src += srcSizeCur;
|
|
||||||
inSize -= srcSizeCur;
|
src += inCur;
|
||||||
*srcLen += srcSizeCur;
|
inSize -= inCur;
|
||||||
outSizeCur = p->decoder.dicPos - dicPos;
|
*srcLen += inCur;
|
||||||
memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
|
outCur = p->decoder.dicPos - dicPos;
|
||||||
dest += outSizeCur;
|
memcpy(dest, p->decoder.dic + dicPos, outCur);
|
||||||
outSize -= outSizeCur;
|
dest += outCur;
|
||||||
*destLen += outSizeCur;
|
outSize -= outCur;
|
||||||
|
*destLen += outCur;
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
return res;
|
return res;
|
||||||
if (outSizeCur == 0 || outSize == 0)
|
if (outCur == 0 || outSize == 0)
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
|
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
CLzma2Dec p;
|
CLzma2Dec p;
|
||||||
SRes res;
|
SRes res;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Lzma2Dec.h -- LZMA2 Decoder
|
/* Lzma2Dec.h -- LZMA2 Decoder
|
||||||
2015-05-13 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZMA2_DEC_H
|
#ifndef __LZMA2_DEC_H
|
||||||
#define __LZMA2_DEC_H
|
#define __LZMA2_DEC_H
|
||||||
@@ -26,8 +26,8 @@ typedef struct
|
|||||||
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
|
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
|
||||||
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
|
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
|
||||||
|
|
||||||
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
|
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
|
||||||
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
|
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
|
||||||
void Lzma2Dec_Init(CLzma2Dec *p);
|
void Lzma2Dec_Init(CLzma2Dec *p);
|
||||||
|
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ Returns:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
|
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc);
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
|
|||||||
688
C/Lzma2Enc.c
688
C/Lzma2Enc.c
@@ -1,9 +1,8 @@
|
|||||||
/* Lzma2Enc.c -- LZMA2 Encoder
|
/* Lzma2Enc.c -- LZMA2 Encoder
|
||||||
2015-10-04 : Igor Pavlov : Public domain */
|
2017-08-28 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
/* #include <stdio.h> */
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* #define _7ZIP_ST */
|
/* #define _7ZIP_ST */
|
||||||
@@ -13,7 +12,7 @@
|
|||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
#include "MtCoder.h"
|
#include "MtCoder.h"
|
||||||
#else
|
#else
|
||||||
#define NUM_MT_CODER_THREADS_MAX 1
|
#define MTCODER__THREADS_MAX 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LZMA2_CONTROL_LZMA (1 << 7)
|
#define LZMA2_CONTROL_LZMA (1 << 7)
|
||||||
@@ -35,34 +34,87 @@
|
|||||||
|
|
||||||
#define PRF(x) /* x */
|
#define PRF(x) /* x */
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------- CLimitedSeqInStream ---------- */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ISeqInStream vt;
|
||||||
|
ISeqInStream *realStream;
|
||||||
|
UInt64 limit;
|
||||||
|
UInt64 processed;
|
||||||
|
int finished;
|
||||||
|
} CLimitedSeqInStream;
|
||||||
|
|
||||||
|
static void LimitedSeqInStream_Init(CLimitedSeqInStream *p)
|
||||||
|
{
|
||||||
|
p->limit = (UInt64)(Int64)-1;
|
||||||
|
p->processed = 0;
|
||||||
|
p->finished = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes LimitedSeqInStream_Read(const ISeqInStream *pp, void *data, size_t *size)
|
||||||
|
{
|
||||||
|
CLimitedSeqInStream *p = CONTAINER_FROM_VTBL(pp, CLimitedSeqInStream, vt);
|
||||||
|
size_t size2 = *size;
|
||||||
|
SRes res = SZ_OK;
|
||||||
|
|
||||||
|
if (p->limit != (UInt64)(Int64)-1)
|
||||||
|
{
|
||||||
|
UInt64 rem = p->limit - p->processed;
|
||||||
|
if (size2 > rem)
|
||||||
|
size2 = (size_t)rem;
|
||||||
|
}
|
||||||
|
if (size2 != 0)
|
||||||
|
{
|
||||||
|
res = ISeqInStream_Read(p->realStream, data, &size2);
|
||||||
|
p->finished = (size2 == 0 ? 1 : 0);
|
||||||
|
p->processed += size2;
|
||||||
|
}
|
||||||
|
*size = size2;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ---------- CLzma2EncInt ---------- */
|
/* ---------- CLzma2EncInt ---------- */
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CLzmaEncHandle enc;
|
CLzmaEncHandle enc;
|
||||||
|
Byte propsAreSet;
|
||||||
|
Byte propsByte;
|
||||||
|
Byte needInitState;
|
||||||
|
Byte needInitProp;
|
||||||
UInt64 srcPos;
|
UInt64 srcPos;
|
||||||
Byte props;
|
|
||||||
Bool needInitState;
|
|
||||||
Bool needInitProp;
|
|
||||||
} CLzma2EncInt;
|
} CLzma2EncInt;
|
||||||
|
|
||||||
static SRes Lzma2EncInt_Init(CLzma2EncInt *p, const CLzma2EncProps *props)
|
|
||||||
|
static SRes Lzma2EncInt_InitStream(CLzma2EncInt *p, const CLzma2EncProps *props)
|
||||||
{
|
{
|
||||||
Byte propsEncoded[LZMA_PROPS_SIZE];
|
if (!p->propsAreSet)
|
||||||
SizeT propsSize = LZMA_PROPS_SIZE;
|
{
|
||||||
RINOK(LzmaEnc_SetProps(p->enc, &props->lzmaProps));
|
SizeT propsSize = LZMA_PROPS_SIZE;
|
||||||
RINOK(LzmaEnc_WriteProperties(p->enc, propsEncoded, &propsSize));
|
Byte propsEncoded[LZMA_PROPS_SIZE];
|
||||||
p->srcPos = 0;
|
RINOK(LzmaEnc_SetProps(p->enc, &props->lzmaProps));
|
||||||
p->props = propsEncoded[0];
|
RINOK(LzmaEnc_WriteProperties(p->enc, propsEncoded, &propsSize));
|
||||||
p->needInitState = True;
|
p->propsByte = propsEncoded[0];
|
||||||
p->needInitProp = True;
|
p->propsAreSet = True;
|
||||||
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Lzma2EncInt_InitBlock(CLzma2EncInt *p)
|
||||||
|
{
|
||||||
|
p->srcPos = 0;
|
||||||
|
p->needInitState = True;
|
||||||
|
p->needInitProp = True;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize,
|
SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize,
|
||||||
ISzAlloc *alloc, ISzAlloc *allocBig);
|
ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
||||||
SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
|
SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
|
||||||
UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig);
|
UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
||||||
SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
|
SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
|
||||||
Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize);
|
Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize);
|
||||||
const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp);
|
const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp);
|
||||||
@@ -70,6 +122,9 @@ void LzmaEnc_Finish(CLzmaEncHandle pp);
|
|||||||
void LzmaEnc_SaveState(CLzmaEncHandle pp);
|
void LzmaEnc_SaveState(CLzmaEncHandle pp);
|
||||||
void LzmaEnc_RestoreState(CLzmaEncHandle pp);
|
void LzmaEnc_RestoreState(CLzmaEncHandle pp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp);
|
||||||
|
*/
|
||||||
|
|
||||||
static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
||||||
size_t *packSizeRes, ISeqOutStream *outStream)
|
size_t *packSizeRes, ISeqOutStream *outStream)
|
||||||
@@ -126,7 +181,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
|||||||
if (outStream)
|
if (outStream)
|
||||||
{
|
{
|
||||||
*packSizeRes += destPos;
|
*packSizeRes += destPos;
|
||||||
if (outStream->Write(outStream, outBuf, destPos) != destPos)
|
if (ISeqOutStream_Write(outStream, outBuf, destPos) != destPos)
|
||||||
return SZ_ERROR_WRITE;
|
return SZ_ERROR_WRITE;
|
||||||
destPos = 0;
|
destPos = 0;
|
||||||
}
|
}
|
||||||
@@ -154,7 +209,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
|||||||
outBuf[destPos++] = (Byte)pm;
|
outBuf[destPos++] = (Byte)pm;
|
||||||
|
|
||||||
if (p->needInitProp)
|
if (p->needInitProp)
|
||||||
outBuf[destPos++] = p->props;
|
outBuf[destPos++] = p->propsByte;
|
||||||
|
|
||||||
p->needInitProp = False;
|
p->needInitProp = False;
|
||||||
p->needInitState = False;
|
p->needInitState = False;
|
||||||
@@ -162,7 +217,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
|||||||
p->srcPos += unpackSize;
|
p->srcPos += unpackSize;
|
||||||
|
|
||||||
if (outStream)
|
if (outStream)
|
||||||
if (outStream->Write(outStream, outBuf, destPos) != destPos)
|
if (ISeqOutStream_Write(outStream, outBuf, destPos) != destPos)
|
||||||
return SZ_ERROR_WRITE;
|
return SZ_ERROR_WRITE;
|
||||||
|
|
||||||
*packSizeRes = destPos;
|
*packSizeRes = destPos;
|
||||||
@@ -176,14 +231,16 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
|||||||
void Lzma2EncProps_Init(CLzma2EncProps *p)
|
void Lzma2EncProps_Init(CLzma2EncProps *p)
|
||||||
{
|
{
|
||||||
LzmaEncProps_Init(&p->lzmaProps);
|
LzmaEncProps_Init(&p->lzmaProps);
|
||||||
|
p->blockSize = LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO;
|
||||||
|
p->numBlockThreads_Reduced = -1;
|
||||||
|
p->numBlockThreads_Max = -1;
|
||||||
p->numTotalThreads = -1;
|
p->numTotalThreads = -1;
|
||||||
p->numBlockThreads = -1;
|
|
||||||
p->blockSize = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lzma2EncProps_Normalize(CLzma2EncProps *p)
|
void Lzma2EncProps_Normalize(CLzma2EncProps *p)
|
||||||
{
|
{
|
||||||
int t1, t1n, t2, t3;
|
UInt64 fileSize;
|
||||||
|
int t1, t1n, t2, t2r, t3;
|
||||||
{
|
{
|
||||||
CLzmaEncProps lzmaProps = p->lzmaProps;
|
CLzmaEncProps lzmaProps = p->lzmaProps;
|
||||||
LzmaEncProps_Normalize(&lzmaProps);
|
LzmaEncProps_Normalize(&lzmaProps);
|
||||||
@@ -191,11 +248,11 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
t1 = p->lzmaProps.numThreads;
|
t1 = p->lzmaProps.numThreads;
|
||||||
t2 = p->numBlockThreads;
|
t2 = p->numBlockThreads_Max;
|
||||||
t3 = p->numTotalThreads;
|
t3 = p->numTotalThreads;
|
||||||
|
|
||||||
if (t2 > NUM_MT_CODER_THREADS_MAX)
|
if (t2 > MTCODER__THREADS_MAX)
|
||||||
t2 = NUM_MT_CODER_THREADS_MAX;
|
t2 = MTCODER__THREADS_MAX;
|
||||||
|
|
||||||
if (t3 <= 0)
|
if (t3 <= 0)
|
||||||
{
|
{
|
||||||
@@ -211,8 +268,8 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
|
|||||||
t1 = 1;
|
t1 = 1;
|
||||||
t2 = t3;
|
t2 = t3;
|
||||||
}
|
}
|
||||||
if (t2 > NUM_MT_CODER_THREADS_MAX)
|
if (t2 > MTCODER__THREADS_MAX)
|
||||||
t2 = NUM_MT_CODER_THREADS_MAX;
|
t2 = MTCODER__THREADS_MAX;
|
||||||
}
|
}
|
||||||
else if (t1 <= 0)
|
else if (t1 <= 0)
|
||||||
{
|
{
|
||||||
@@ -225,46 +282,71 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
|
|||||||
|
|
||||||
p->lzmaProps.numThreads = t1;
|
p->lzmaProps.numThreads = t1;
|
||||||
|
|
||||||
|
t2r = t2;
|
||||||
|
|
||||||
|
fileSize = p->lzmaProps.reduceSize;
|
||||||
|
|
||||||
|
if ( p->blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID
|
||||||
|
&& p->blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO
|
||||||
|
&& (p->blockSize < fileSize || fileSize == (UInt64)(Int64)-1))
|
||||||
|
p->lzmaProps.reduceSize = p->blockSize;
|
||||||
|
|
||||||
LzmaEncProps_Normalize(&p->lzmaProps);
|
LzmaEncProps_Normalize(&p->lzmaProps);
|
||||||
|
|
||||||
|
p->lzmaProps.reduceSize = fileSize;
|
||||||
|
|
||||||
t1 = p->lzmaProps.numThreads;
|
t1 = p->lzmaProps.numThreads;
|
||||||
|
|
||||||
if (p->blockSize == 0)
|
if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID)
|
||||||
{
|
{
|
||||||
UInt32 dictSize = p->lzmaProps.dictSize;
|
t2r = t2 = 1;
|
||||||
UInt64 blockSize = (UInt64)dictSize << 2;
|
t3 = t1;
|
||||||
const UInt32 kMinSize = (UInt32)1 << 20;
|
|
||||||
const UInt32 kMaxSize = (UInt32)1 << 28;
|
|
||||||
if (blockSize < kMinSize) blockSize = kMinSize;
|
|
||||||
if (blockSize > kMaxSize) blockSize = kMaxSize;
|
|
||||||
if (blockSize < dictSize) blockSize = dictSize;
|
|
||||||
p->blockSize = (size_t)blockSize;
|
|
||||||
}
|
}
|
||||||
|
else if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO && t2 <= 1)
|
||||||
if (t2 > 1 && p->lzmaProps.reduceSize != (UInt64)(Int64)-1)
|
|
||||||
{
|
{
|
||||||
UInt64 temp = p->lzmaProps.reduceSize + p->blockSize - 1;
|
/* if there is no block multi-threading, we use SOLID block */
|
||||||
if (temp > p->lzmaProps.reduceSize)
|
p->blockSize = LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (p->blockSize == LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO)
|
||||||
{
|
{
|
||||||
UInt64 numBlocks = temp / p->blockSize;
|
const UInt32 kMinSize = (UInt32)1 << 20;
|
||||||
|
const UInt32 kMaxSize = (UInt32)1 << 28;
|
||||||
|
const UInt32 dictSize = p->lzmaProps.dictSize;
|
||||||
|
UInt64 blockSize = (UInt64)dictSize << 2;
|
||||||
|
if (blockSize < kMinSize) blockSize = kMinSize;
|
||||||
|
if (blockSize > kMaxSize) blockSize = kMaxSize;
|
||||||
|
if (blockSize < dictSize) blockSize = dictSize;
|
||||||
|
blockSize += (kMinSize - 1);
|
||||||
|
blockSize &= ~(UInt64)(kMinSize - 1);
|
||||||
|
p->blockSize = blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t2 > 1 && fileSize != (UInt64)(Int64)-1)
|
||||||
|
{
|
||||||
|
UInt64 numBlocks = fileSize / p->blockSize;
|
||||||
|
if (numBlocks * p->blockSize != fileSize)
|
||||||
|
numBlocks++;
|
||||||
if (numBlocks < (unsigned)t2)
|
if (numBlocks < (unsigned)t2)
|
||||||
{
|
{
|
||||||
t2 = (unsigned)numBlocks;
|
t2r = (unsigned)numBlocks;
|
||||||
if (t2 == 0)
|
if (t2r == 0)
|
||||||
t2 = 1;
|
t2r = 1;
|
||||||
t3 = t1 * t2;
|
t3 = t1 * t2r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p->numBlockThreads = t2;
|
p->numBlockThreads_Max = t2;
|
||||||
|
p->numBlockThreads_Reduced = t2r;
|
||||||
p->numTotalThreads = t3;
|
p->numTotalThreads = t3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
|
static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
|
||||||
{
|
{
|
||||||
return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
|
return (p && ICompressProgress_Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -274,180 +356,110 @@ typedef struct
|
|||||||
{
|
{
|
||||||
Byte propEncoded;
|
Byte propEncoded;
|
||||||
CLzma2EncProps props;
|
CLzma2EncProps props;
|
||||||
|
UInt64 expectedDataSize;
|
||||||
|
|
||||||
Byte *outBuf;
|
Byte *tempBufLzma;
|
||||||
|
|
||||||
ISzAlloc *alloc;
|
ISzAllocPtr alloc;
|
||||||
ISzAlloc *allocBig;
|
ISzAllocPtr allocBig;
|
||||||
|
|
||||||
CLzma2EncInt coders[NUM_MT_CODER_THREADS_MAX];
|
CLzma2EncInt coders[MTCODER__THREADS_MAX];
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
|
|
||||||
|
ISeqOutStream *outStream;
|
||||||
|
Byte *outBuf;
|
||||||
|
size_t outBufSize;
|
||||||
|
size_t outBufsDataSizes[MTCODER__BLOCKS_MAX];
|
||||||
|
Bool mtCoder_WasConstructed;
|
||||||
CMtCoder mtCoder;
|
CMtCoder mtCoder;
|
||||||
|
Byte *outBufs[MTCODER__BLOCKS_MAX];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} CLzma2Enc;
|
} CLzma2Enc;
|
||||||
|
|
||||||
|
|
||||||
/* ---------- Lzma2EncThread ---------- */
|
|
||||||
|
|
||||||
static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
|
CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
||||||
ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress)
|
|
||||||
{
|
{
|
||||||
UInt64 packTotal = 0;
|
CLzma2Enc *p = (CLzma2Enc *)ISzAlloc_Alloc(alloc, sizeof(CLzma2Enc));
|
||||||
SRes res = SZ_OK;
|
|
||||||
|
|
||||||
if (!mainEncoder->outBuf)
|
|
||||||
{
|
|
||||||
mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
|
|
||||||
if (!mainEncoder->outBuf)
|
|
||||||
return SZ_ERROR_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
RINOK(Lzma2EncInt_Init(p, &mainEncoder->props));
|
|
||||||
RINOK(LzmaEnc_PrepareForLzma2(p->enc, inStream, LZMA2_KEEP_WINDOW_SIZE,
|
|
||||||
mainEncoder->alloc, mainEncoder->allocBig));
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX;
|
|
||||||
res = Lzma2EncInt_EncodeSubblock(p, mainEncoder->outBuf, &packSize, outStream);
|
|
||||||
if (res != SZ_OK)
|
|
||||||
break;
|
|
||||||
packTotal += packSize;
|
|
||||||
res = Progress(progress, p->srcPos, packTotal);
|
|
||||||
if (res != SZ_OK)
|
|
||||||
break;
|
|
||||||
if (packSize == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
LzmaEnc_Finish(p->enc);
|
|
||||||
|
|
||||||
if (res == SZ_OK)
|
|
||||||
{
|
|
||||||
Byte b = 0;
|
|
||||||
if (outStream->Write(outStream, &b, 1) != 1)
|
|
||||||
return SZ_ERROR_WRITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
IMtCoderCallback funcTable;
|
|
||||||
CLzma2Enc *lzma2Enc;
|
|
||||||
} CMtCallbackImp;
|
|
||||||
|
|
||||||
static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *destSize,
|
|
||||||
const Byte *src, size_t srcSize, int finished)
|
|
||||||
{
|
|
||||||
CMtCallbackImp *imp = (CMtCallbackImp *)pp;
|
|
||||||
CLzma2Enc *mainEncoder = imp->lzma2Enc;
|
|
||||||
CLzma2EncInt *p = &mainEncoder->coders[index];
|
|
||||||
|
|
||||||
SRes res = SZ_OK;
|
|
||||||
{
|
|
||||||
size_t destLim = *destSize;
|
|
||||||
*destSize = 0;
|
|
||||||
|
|
||||||
if (srcSize != 0)
|
|
||||||
{
|
|
||||||
RINOK(Lzma2EncInt_Init(p, &mainEncoder->props));
|
|
||||||
|
|
||||||
RINOK(LzmaEnc_MemPrepare(p->enc, src, srcSize, LZMA2_KEEP_WINDOW_SIZE,
|
|
||||||
mainEncoder->alloc, mainEncoder->allocBig));
|
|
||||||
|
|
||||||
while (p->srcPos < srcSize)
|
|
||||||
{
|
|
||||||
size_t packSize = destLim - *destSize;
|
|
||||||
res = Lzma2EncInt_EncodeSubblock(p, dest + *destSize, &packSize, NULL);
|
|
||||||
if (res != SZ_OK)
|
|
||||||
break;
|
|
||||||
*destSize += packSize;
|
|
||||||
|
|
||||||
if (packSize == 0)
|
|
||||||
{
|
|
||||||
res = SZ_ERROR_FAIL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MtProgress_Set(&mainEncoder->mtCoder.mtProgress, index, p->srcPos, *destSize) != SZ_OK)
|
|
||||||
{
|
|
||||||
res = SZ_ERROR_PROGRESS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LzmaEnc_Finish(p->enc);
|
|
||||||
if (res != SZ_OK)
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (finished)
|
|
||||||
{
|
|
||||||
if (*destSize == destLim)
|
|
||||||
return SZ_ERROR_OUTPUT_EOF;
|
|
||||||
dest[(*destSize)++] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ---------- Lzma2Enc ---------- */
|
|
||||||
|
|
||||||
CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)
|
|
||||||
{
|
|
||||||
CLzma2Enc *p = (CLzma2Enc *)alloc->Alloc(alloc, sizeof(CLzma2Enc));
|
|
||||||
if (!p)
|
if (!p)
|
||||||
return NULL;
|
return NULL;
|
||||||
Lzma2EncProps_Init(&p->props);
|
Lzma2EncProps_Init(&p->props);
|
||||||
Lzma2EncProps_Normalize(&p->props);
|
Lzma2EncProps_Normalize(&p->props);
|
||||||
p->outBuf = 0;
|
p->expectedDataSize = (UInt64)(Int64)-1;
|
||||||
|
p->tempBufLzma = NULL;
|
||||||
p->alloc = alloc;
|
p->alloc = alloc;
|
||||||
p->allocBig = allocBig;
|
p->allocBig = allocBig;
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
|
for (i = 0; i < MTCODER__THREADS_MAX; i++)
|
||||||
p->coders[i].enc = 0;
|
p->coders[i].enc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
MtCoder_Construct(&p->mtCoder);
|
p->mtCoder_WasConstructed = False;
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < MTCODER__BLOCKS_MAX; i++)
|
||||||
|
p->outBufs[i] = NULL;
|
||||||
|
p->outBufSize = 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
|
||||||
|
static void Lzma2Enc_FreeOutBufs(CLzma2Enc *p)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < MTCODER__BLOCKS_MAX; i++)
|
||||||
|
if (p->outBufs[i])
|
||||||
|
{
|
||||||
|
ISzAlloc_Free(p->alloc, p->outBufs[i]);
|
||||||
|
p->outBufs[i] = NULL;
|
||||||
|
}
|
||||||
|
p->outBufSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void Lzma2Enc_Destroy(CLzma2EncHandle pp)
|
void Lzma2Enc_Destroy(CLzma2EncHandle pp)
|
||||||
{
|
{
|
||||||
CLzma2Enc *p = (CLzma2Enc *)pp;
|
CLzma2Enc *p = (CLzma2Enc *)pp;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
|
for (i = 0; i < MTCODER__THREADS_MAX; i++)
|
||||||
{
|
{
|
||||||
CLzma2EncInt *t = &p->coders[i];
|
CLzma2EncInt *t = &p->coders[i];
|
||||||
if (t->enc)
|
if (t->enc)
|
||||||
{
|
{
|
||||||
LzmaEnc_Destroy(t->enc, p->alloc, p->allocBig);
|
LzmaEnc_Destroy(t->enc, p->alloc, p->allocBig);
|
||||||
t->enc = 0;
|
t->enc = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
MtCoder_Destruct(&p->mtCoder);
|
if (p->mtCoder_WasConstructed)
|
||||||
|
{
|
||||||
|
MtCoder_Destruct(&p->mtCoder);
|
||||||
|
p->mtCoder_WasConstructed = False;
|
||||||
|
}
|
||||||
|
Lzma2Enc_FreeOutBufs(p);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IAlloc_Free(p->alloc, p->outBuf);
|
ISzAlloc_Free(p->alloc, p->tempBufLzma);
|
||||||
IAlloc_Free(p->alloc, pp);
|
p->tempBufLzma = NULL;
|
||||||
|
|
||||||
|
ISzAlloc_Free(p->alloc, pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props)
|
SRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props)
|
||||||
{
|
{
|
||||||
CLzma2Enc *p = (CLzma2Enc *)pp;
|
CLzma2Enc *p = (CLzma2Enc *)pp;
|
||||||
@@ -460,6 +472,14 @@ SRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props)
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Lzma2Enc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize)
|
||||||
|
{
|
||||||
|
CLzma2Enc *p = (CLzma2Enc *)pp;
|
||||||
|
p->expectedDataSize = expectedDataSiize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Byte Lzma2Enc_WriteProperties(CLzma2EncHandle pp)
|
Byte Lzma2Enc_WriteProperties(CLzma2EncHandle pp)
|
||||||
{
|
{
|
||||||
CLzma2Enc *p = (CLzma2Enc *)pp;
|
CLzma2Enc *p = (CLzma2Enc *)pp;
|
||||||
@@ -471,50 +491,310 @@ Byte Lzma2Enc_WriteProperties(CLzma2EncHandle pp)
|
|||||||
return (Byte)i;
|
return (Byte)i;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
|
|
||||||
ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress)
|
|
||||||
{
|
|
||||||
CLzma2Enc *p = (CLzma2Enc *)pp;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < p->props.numBlockThreads; i++)
|
static SRes Lzma2Enc_EncodeMt1(
|
||||||
|
CLzma2Enc *me,
|
||||||
|
CLzma2EncInt *p,
|
||||||
|
ISeqOutStream *outStream,
|
||||||
|
Byte *outBuf, size_t *outBufSize,
|
||||||
|
ISeqInStream *inStream,
|
||||||
|
const Byte *inData, size_t inDataSize,
|
||||||
|
int finished,
|
||||||
|
ICompressProgress *progress)
|
||||||
|
{
|
||||||
|
UInt64 unpackTotal = 0;
|
||||||
|
UInt64 packTotal = 0;
|
||||||
|
size_t outLim = 0;
|
||||||
|
CLimitedSeqInStream limitedInStream;
|
||||||
|
|
||||||
|
if (outBuf)
|
||||||
{
|
{
|
||||||
CLzma2EncInt *t = &p->coders[(unsigned)i];
|
outLim = *outBufSize;
|
||||||
if (!t->enc)
|
*outBufSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p->enc)
|
||||||
|
{
|
||||||
|
p->propsAreSet = False;
|
||||||
|
p->enc = LzmaEnc_Create(me->alloc);
|
||||||
|
if (!p->enc)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
limitedInStream.realStream = inStream;
|
||||||
|
if (inStream)
|
||||||
|
{
|
||||||
|
limitedInStream.vt.Read = LimitedSeqInStream_Read;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!outBuf)
|
||||||
|
{
|
||||||
|
// outStream version works only in one thread. So we use CLzma2Enc::tempBufLzma
|
||||||
|
if (!me->tempBufLzma)
|
||||||
{
|
{
|
||||||
t->enc = LzmaEnc_Create(p->alloc);
|
me->tempBufLzma = (Byte *)ISzAlloc_Alloc(me->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
|
||||||
if (!t->enc)
|
if (!me->tempBufLzma)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
RINOK(Lzma2EncInt_InitStream(p, &me->props));
|
||||||
if (p->props.numBlockThreads > 1)
|
|
||||||
{
|
|
||||||
CMtCallbackImp mtCallback;
|
|
||||||
|
|
||||||
mtCallback.funcTable.Code = MtCallbackImp_Code;
|
for (;;)
|
||||||
mtCallback.lzma2Enc = p;
|
{
|
||||||
|
SRes res = SZ_OK;
|
||||||
|
size_t inSizeCur = 0;
|
||||||
|
|
||||||
|
Lzma2EncInt_InitBlock(p);
|
||||||
|
|
||||||
|
LimitedSeqInStream_Init(&limitedInStream);
|
||||||
|
limitedInStream.limit = me->props.blockSize;
|
||||||
|
|
||||||
|
if (inStream)
|
||||||
|
{
|
||||||
|
UInt64 expected = (UInt64)(Int64)-1;
|
||||||
|
// inStream version works only in one thread. So we use CLzma2Enc::expectedDataSize
|
||||||
|
if (me->expectedDataSize != (UInt64)(Int64)-1
|
||||||
|
&& me->expectedDataSize >= unpackTotal)
|
||||||
|
expected = me->expectedDataSize - unpackTotal;
|
||||||
|
if (me->props.blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID
|
||||||
|
&& expected > me->props.blockSize)
|
||||||
|
expected = (size_t)me->props.blockSize;
|
||||||
|
|
||||||
|
LzmaEnc_SetDataSize(p->enc, expected);
|
||||||
|
|
||||||
|
RINOK(LzmaEnc_PrepareForLzma2(p->enc,
|
||||||
|
&limitedInStream.vt,
|
||||||
|
LZMA2_KEEP_WINDOW_SIZE,
|
||||||
|
me->alloc,
|
||||||
|
me->allocBig));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inSizeCur = inDataSize - (size_t)unpackTotal;
|
||||||
|
if (me->props.blockSize != LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID
|
||||||
|
&& inSizeCur > me->props.blockSize)
|
||||||
|
inSizeCur = (size_t)me->props.blockSize;
|
||||||
|
|
||||||
|
// LzmaEnc_SetDataSize(p->enc, inSizeCur);
|
||||||
|
|
||||||
|
RINOK(LzmaEnc_MemPrepare(p->enc,
|
||||||
|
inData + (size_t)unpackTotal, inSizeCur,
|
||||||
|
LZMA2_KEEP_WINDOW_SIZE,
|
||||||
|
me->alloc,
|
||||||
|
me->allocBig));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX;
|
||||||
|
if (outBuf)
|
||||||
|
packSize = outLim - (size_t)packTotal;
|
||||||
|
|
||||||
|
res = Lzma2EncInt_EncodeSubblock(p,
|
||||||
|
outBuf ? outBuf + (size_t)packTotal : me->tempBufLzma, &packSize,
|
||||||
|
outBuf ? NULL : outStream);
|
||||||
|
|
||||||
|
if (res != SZ_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
packTotal += packSize;
|
||||||
|
if (outBuf)
|
||||||
|
*outBufSize = (size_t)packTotal;
|
||||||
|
|
||||||
|
res = Progress(progress, unpackTotal + p->srcPos, packTotal);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (LzmaEnc_GetNumAvailableBytes(p->enc) == 0)
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (packSize == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LzmaEnc_Finish(p->enc);
|
||||||
|
|
||||||
|
unpackTotal += p->srcPos;
|
||||||
|
|
||||||
|
RINOK(res);
|
||||||
|
|
||||||
|
if (p->srcPos != (inStream ? limitedInStream.processed : inSizeCur))
|
||||||
|
return SZ_ERROR_FAIL;
|
||||||
|
|
||||||
|
if (inStream ? limitedInStream.finished : (unpackTotal == inDataSize))
|
||||||
|
{
|
||||||
|
if (finished)
|
||||||
|
{
|
||||||
|
if (outBuf)
|
||||||
|
{
|
||||||
|
size_t destPos = *outBufSize;
|
||||||
|
if (destPos >= outLim)
|
||||||
|
return SZ_ERROR_OUTPUT_EOF;
|
||||||
|
outBuf[destPos] = 0;
|
||||||
|
*outBufSize = destPos + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Byte b = 0;
|
||||||
|
if (ISeqOutStream_Write(outStream, &b, 1) != 1)
|
||||||
|
return SZ_ERROR_WRITE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
|
||||||
|
static SRes Lzma2Enc_MtCallback_Code(void *pp, unsigned coderIndex, unsigned outBufIndex,
|
||||||
|
const Byte *src, size_t srcSize, int finished)
|
||||||
|
{
|
||||||
|
CLzma2Enc *me = (CLzma2Enc *)pp;
|
||||||
|
size_t destSize = me->outBufSize;
|
||||||
|
SRes res;
|
||||||
|
CMtProgressThunk progressThunk;
|
||||||
|
|
||||||
|
Byte *dest = me->outBufs[outBufIndex];
|
||||||
|
|
||||||
|
me->outBufsDataSizes[outBufIndex] = 0;
|
||||||
|
|
||||||
|
if (!dest)
|
||||||
|
{
|
||||||
|
dest = ISzAlloc_Alloc(me->alloc, me->outBufSize);
|
||||||
|
if (!dest)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
me->outBufs[outBufIndex] = dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
MtProgressThunk_CreateVTable(&progressThunk);
|
||||||
|
progressThunk.mtProgress = &me->mtCoder.mtProgress;
|
||||||
|
progressThunk.index = coderIndex;
|
||||||
|
|
||||||
|
res = Lzma2Enc_EncodeMt1(me,
|
||||||
|
&me->coders[coderIndex],
|
||||||
|
NULL, dest, &destSize,
|
||||||
|
NULL, src, srcSize,
|
||||||
|
finished,
|
||||||
|
&progressThunk.vt);
|
||||||
|
|
||||||
|
me->outBufsDataSizes[outBufIndex] = destSize;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static SRes Lzma2Enc_MtCallback_Write(void *pp, unsigned outBufIndex)
|
||||||
|
{
|
||||||
|
CLzma2Enc *me = (CLzma2Enc *)pp;
|
||||||
|
size_t size = me->outBufsDataSizes[outBufIndex];
|
||||||
|
const Byte *data = me->outBufs[outBufIndex];
|
||||||
|
|
||||||
|
if (me->outStream)
|
||||||
|
return ISeqOutStream_Write(me->outStream, data, size) == size ? SZ_OK : SZ_ERROR_WRITE;
|
||||||
|
|
||||||
|
if (size > me->outBufSize)
|
||||||
|
return SZ_ERROR_OUTPUT_EOF;
|
||||||
|
memcpy(me->outBuf, data, size);
|
||||||
|
me->outBufSize -= size;
|
||||||
|
me->outBuf += size;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SRes Lzma2Enc_Encode2(CLzma2EncHandle pp,
|
||||||
|
ISeqOutStream *outStream,
|
||||||
|
Byte *outBuf, size_t *outBufSize,
|
||||||
|
ISeqInStream *inStream,
|
||||||
|
const Byte *inData, size_t inDataSize,
|
||||||
|
ICompressProgress *progress)
|
||||||
|
{
|
||||||
|
CLzma2Enc *p = (CLzma2Enc *)pp;
|
||||||
|
|
||||||
|
if (inStream && inData)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (outStream && outBuf)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < MTCODER__THREADS_MAX; i++)
|
||||||
|
p->coders[i].propsAreSet = False;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
|
||||||
|
if (p->props.numBlockThreads_Reduced > 1)
|
||||||
|
{
|
||||||
|
IMtCoderCallback2 vt;
|
||||||
|
|
||||||
|
if (!p->mtCoder_WasConstructed)
|
||||||
|
{
|
||||||
|
p->mtCoder_WasConstructed = True;
|
||||||
|
MtCoder_Construct(&p->mtCoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
vt.Code = Lzma2Enc_MtCallback_Code;
|
||||||
|
vt.Write = Lzma2Enc_MtCallback_Write;
|
||||||
|
|
||||||
|
p->outStream = outStream;
|
||||||
|
p->outBuf = NULL;
|
||||||
|
p->outBufSize = 0;
|
||||||
|
if (!outStream)
|
||||||
|
{
|
||||||
|
p->outBuf = outBuf;
|
||||||
|
p->outBufSize = *outBufSize;
|
||||||
|
*outBufSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->mtCoder.allocBig = p->allocBig;
|
||||||
p->mtCoder.progress = progress;
|
p->mtCoder.progress = progress;
|
||||||
p->mtCoder.inStream = inStream;
|
p->mtCoder.inStream = inStream;
|
||||||
p->mtCoder.outStream = outStream;
|
p->mtCoder.inData = inData;
|
||||||
p->mtCoder.alloc = p->alloc;
|
p->mtCoder.inDataSize = inDataSize;
|
||||||
p->mtCoder.mtCallback = &mtCallback.funcTable;
|
p->mtCoder.mtCallback = &vt;
|
||||||
|
p->mtCoder.mtCallbackObject = p;
|
||||||
|
|
||||||
|
p->mtCoder.blockSize = (size_t)p->props.blockSize;
|
||||||
|
if (p->mtCoder.blockSize != p->props.blockSize)
|
||||||
|
return SZ_ERROR_PARAM; /* SZ_ERROR_MEM */
|
||||||
|
|
||||||
p->mtCoder.blockSize = p->props.blockSize;
|
|
||||||
p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16;
|
|
||||||
if (p->mtCoder.destBlockSize < p->props.blockSize)
|
|
||||||
{
|
{
|
||||||
p->mtCoder.destBlockSize = (size_t)0 - 1;
|
size_t destBlockSize = p->mtCoder.blockSize + (p->mtCoder.blockSize >> 10) + 16;
|
||||||
if (p->mtCoder.destBlockSize < p->props.blockSize)
|
if (destBlockSize < p->mtCoder.blockSize)
|
||||||
return SZ_ERROR_FAIL;
|
return SZ_ERROR_PARAM;
|
||||||
|
if (p->outBufSize != destBlockSize)
|
||||||
|
Lzma2Enc_FreeOutBufs(p);
|
||||||
|
p->outBufSize = destBlockSize;
|
||||||
}
|
}
|
||||||
p->mtCoder.numThreads = p->props.numBlockThreads;
|
|
||||||
|
p->mtCoder.numThreadsMax = p->props.numBlockThreads_Max;
|
||||||
|
p->mtCoder.expectedDataSize = p->expectedDataSize;
|
||||||
|
|
||||||
return MtCoder_Code(&p->mtCoder);
|
{
|
||||||
|
SRes res = MtCoder_Code(&p->mtCoder);
|
||||||
|
if (!outStream)
|
||||||
|
*outBufSize = p->outBuf - outBuf;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);
|
|
||||||
|
return Lzma2Enc_EncodeMt1(p,
|
||||||
|
&p->coders[0],
|
||||||
|
outStream, outBuf, outBufSize,
|
||||||
|
inStream, inData, inDataSize,
|
||||||
|
True, /* finished */
|
||||||
|
progress);
|
||||||
}
|
}
|
||||||
|
|||||||
45
C/Lzma2Enc.h
45
C/Lzma2Enc.h
@@ -1,5 +1,5 @@
|
|||||||
/* Lzma2Enc.h -- LZMA2 Encoder
|
/* Lzma2Enc.h -- LZMA2 Encoder
|
||||||
2013-01-18 : Igor Pavlov : Public domain */
|
2017-07-27 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZMA2_ENC_H
|
#ifndef __LZMA2_ENC_H
|
||||||
#define __LZMA2_ENC_H
|
#define __LZMA2_ENC_H
|
||||||
@@ -8,11 +8,15 @@
|
|||||||
|
|
||||||
EXTERN_C_BEGIN
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
#define LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO 0
|
||||||
|
#define LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID ((UInt64)(Int64)-1)
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CLzmaEncProps lzmaProps;
|
CLzmaEncProps lzmaProps;
|
||||||
size_t blockSize;
|
UInt64 blockSize;
|
||||||
int numBlockThreads;
|
int numBlockThreads_Reduced;
|
||||||
|
int numBlockThreads_Max;
|
||||||
int numTotalThreads;
|
int numTotalThreads;
|
||||||
} CLzma2EncProps;
|
} CLzma2EncProps;
|
||||||
|
|
||||||
@@ -22,40 +26,29 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p);
|
|||||||
/* ---------- CLzmaEnc2Handle Interface ---------- */
|
/* ---------- CLzmaEnc2Handle Interface ---------- */
|
||||||
|
|
||||||
/* Lzma2Enc_* functions can return the following exit codes:
|
/* Lzma2Enc_* functions can return the following exit codes:
|
||||||
Returns:
|
SRes:
|
||||||
SZ_OK - OK
|
SZ_OK - OK
|
||||||
SZ_ERROR_MEM - Memory allocation error
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
SZ_ERROR_PARAM - Incorrect paramater in props
|
SZ_ERROR_PARAM - Incorrect paramater in props
|
||||||
SZ_ERROR_WRITE - Write callback error
|
SZ_ERROR_WRITE - ISeqOutStream write callback error
|
||||||
|
SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
|
||||||
SZ_ERROR_PROGRESS - some break from progress callback
|
SZ_ERROR_PROGRESS - some break from progress callback
|
||||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef void * CLzma2EncHandle;
|
typedef void * CLzma2EncHandle;
|
||||||
|
|
||||||
CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig);
|
CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
||||||
void Lzma2Enc_Destroy(CLzma2EncHandle p);
|
void Lzma2Enc_Destroy(CLzma2EncHandle p);
|
||||||
SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props);
|
SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props);
|
||||||
|
void Lzma2Enc_SetDataSize(CLzma2EncHandle p, UInt64 expectedDataSiize);
|
||||||
Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p);
|
Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p);
|
||||||
SRes Lzma2Enc_Encode(CLzma2EncHandle p,
|
SRes Lzma2Enc_Encode2(CLzma2EncHandle p,
|
||||||
ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress);
|
ISeqOutStream *outStream,
|
||||||
|
Byte *outBuf, size_t *outBufSize,
|
||||||
/* ---------- One Call Interface ---------- */
|
ISeqInStream *inStream,
|
||||||
|
const Byte *inData, size_t inDataSize,
|
||||||
/* Lzma2Encode
|
ICompressProgress *progress);
|
||||||
Return code:
|
|
||||||
SZ_OK - OK
|
|
||||||
SZ_ERROR_MEM - Memory allocation error
|
|
||||||
SZ_ERROR_PARAM - Incorrect paramater
|
|
||||||
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
|
||||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
SRes Lzma2Encode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
|
||||||
const CLzmaEncProps *props, Byte *propsEncoded, int writeEndMark,
|
|
||||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
|
||||||
*/
|
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder
|
/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder
|
||||||
2015-11-08 : Igor Pavlov : Public domain */
|
2016-05-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -9,9 +9,6 @@
|
|||||||
#include "Bra.h"
|
#include "Bra.h"
|
||||||
#include "LzmaDec.h"
|
#include "LzmaDec.h"
|
||||||
|
|
||||||
static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
|
|
||||||
static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
|
|
||||||
|
|
||||||
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
|
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@@ -25,7 +22,6 @@ SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
|
|||||||
|
|
||||||
SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen)
|
SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen)
|
||||||
{
|
{
|
||||||
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
|
||||||
SRes res;
|
SRes res;
|
||||||
int useFilter;
|
int useFilter;
|
||||||
SizeT inSizePure;
|
SizeT inSizePure;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
|
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
|
||||||
2015-11-08 : Igor Pavlov : Public domain */
|
2016-05-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -13,13 +13,9 @@
|
|||||||
|
|
||||||
#define SZE_OUT_OVERFLOW SZE_DATA_ERROR
|
#define SZE_OUT_OVERFLOW SZE_DATA_ERROR
|
||||||
|
|
||||||
static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
|
|
||||||
static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
|
|
||||||
|
|
||||||
int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
||||||
int level, UInt32 dictSize, int filterMode)
|
int level, UInt32 dictSize, int filterMode)
|
||||||
{
|
{
|
||||||
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
|
||||||
size_t outSize2 = *destLen;
|
size_t outSize2 = *destLen;
|
||||||
Byte *filteredStream;
|
Byte *filteredStream;
|
||||||
Bool useFilter;
|
Bool useFilter;
|
||||||
|
|||||||
34
C/LzmaDec.c
34
C/LzmaDec.c
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaDec.c -- LZMA Decoder
|
/* LzmaDec.c -- LZMA Decoder
|
||||||
2015-06-23 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -294,14 +294,14 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
|
|
||||||
#ifdef _LZMA_SIZE_OPT
|
#ifdef _LZMA_SIZE_OPT
|
||||||
{
|
{
|
||||||
unsigned limit, offset;
|
unsigned lim, offset;
|
||||||
CLzmaProb *probLen = prob + LenChoice;
|
CLzmaProb *probLen = prob + LenChoice;
|
||||||
IF_BIT_0(probLen)
|
IF_BIT_0(probLen)
|
||||||
{
|
{
|
||||||
UPDATE_0(probLen);
|
UPDATE_0(probLen);
|
||||||
probLen = prob + LenLow + (posState << kLenNumLowBits);
|
probLen = prob + LenLow + (posState << kLenNumLowBits);
|
||||||
offset = 0;
|
offset = 0;
|
||||||
limit = (1 << kLenNumLowBits);
|
lim = (1 << kLenNumLowBits);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -312,17 +312,17 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
UPDATE_0(probLen);
|
UPDATE_0(probLen);
|
||||||
probLen = prob + LenMid + (posState << kLenNumMidBits);
|
probLen = prob + LenMid + (posState << kLenNumMidBits);
|
||||||
offset = kLenNumLowSymbols;
|
offset = kLenNumLowSymbols;
|
||||||
limit = (1 << kLenNumMidBits);
|
lim = (1 << kLenNumMidBits);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1(probLen);
|
UPDATE_1(probLen);
|
||||||
probLen = prob + LenHigh;
|
probLen = prob + LenHigh;
|
||||||
offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
||||||
limit = (1 << kLenNumHighBits);
|
lim = (1 << kLenNumHighBits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TREE_DECODE(probLen, limit, len);
|
TREE_DECODE(probLen, lim, len);
|
||||||
len += offset;
|
len += offset;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -975,19 +975,19 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
|
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->probs);
|
ISzAlloc_Free(alloc, p->probs);
|
||||||
p->probs = NULL;
|
p->probs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
|
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->dic);
|
ISzAlloc_Free(alloc, p->dic);
|
||||||
p->dic = NULL;
|
p->dic = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
|
void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
LzmaDec_FreeProbs(p, alloc);
|
LzmaDec_FreeProbs(p, alloc);
|
||||||
LzmaDec_FreeDict(p, alloc);
|
LzmaDec_FreeDict(p, alloc);
|
||||||
@@ -1019,13 +1019,13 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
|
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
|
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
|
||||||
if (!p->probs || numProbs != p->numProbs)
|
if (!p->probs || numProbs != p->numProbs)
|
||||||
{
|
{
|
||||||
LzmaDec_FreeProbs(p, alloc);
|
LzmaDec_FreeProbs(p, alloc);
|
||||||
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
|
p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb));
|
||||||
p->numProbs = numProbs;
|
p->numProbs = numProbs;
|
||||||
if (!p->probs)
|
if (!p->probs)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
@@ -1033,7 +1033,7 @@ static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAl
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
|
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
CLzmaProps propNew;
|
CLzmaProps propNew;
|
||||||
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
|
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
|
||||||
@@ -1042,7 +1042,7 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, I
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
|
SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
CLzmaProps propNew;
|
CLzmaProps propNew;
|
||||||
SizeT dicBufSize;
|
SizeT dicBufSize;
|
||||||
@@ -1062,7 +1062,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
|
|||||||
if (!p->dic || dicBufSize != p->dicBufSize)
|
if (!p->dic || dicBufSize != p->dicBufSize)
|
||||||
{
|
{
|
||||||
LzmaDec_FreeDict(p, alloc);
|
LzmaDec_FreeDict(p, alloc);
|
||||||
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
|
p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize);
|
||||||
if (!p->dic)
|
if (!p->dic)
|
||||||
{
|
{
|
||||||
LzmaDec_FreeProbs(p, alloc);
|
LzmaDec_FreeProbs(p, alloc);
|
||||||
@@ -1076,7 +1076,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
|
|||||||
|
|
||||||
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||||
ELzmaStatus *status, ISzAlloc *alloc)
|
ELzmaStatus *status, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
CLzmaDec p;
|
CLzmaDec p;
|
||||||
SRes res;
|
SRes res;
|
||||||
|
|||||||
12
C/LzmaDec.h
12
C/LzmaDec.h
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaDec.h -- LZMA Decoder
|
/* LzmaDec.h -- LZMA Decoder
|
||||||
2013-01-18 : Igor Pavlov : Public domain */
|
2017-04-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZMA_DEC_H
|
#ifndef __LZMA_DEC_H
|
||||||
#define __LZMA_DEC_H
|
#define __LZMA_DEC_H
|
||||||
@@ -129,11 +129,11 @@ LzmaDec_Allocate* can return:
|
|||||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
|
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
|
||||||
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
|
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc);
|
||||||
|
|
||||||
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
|
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAllocPtr alloc);
|
||||||
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
void LzmaDec_Free(CLzmaDec *state, ISzAllocPtr alloc);
|
||||||
|
|
||||||
/* ---------- Dictionary Interface ---------- */
|
/* ---------- Dictionary Interface ---------- */
|
||||||
|
|
||||||
@@ -220,7 +220,7 @@ Returns:
|
|||||||
|
|
||||||
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||||
ELzmaStatus *status, ISzAlloc *alloc);
|
ELzmaStatus *status, ISzAllocPtr alloc);
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
|
|||||||
194
C/LzmaEnc.c
194
C/LzmaEnc.c
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaEnc.c -- LZMA Encoder
|
/* LzmaEnc.c -- LZMA Encoder
|
||||||
2015-11-08 : Igor Pavlov : Public domain */
|
2017-06-22 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -23,8 +23,8 @@
|
|||||||
static unsigned g_STAT_OFFSET = 0;
|
static unsigned g_STAT_OFFSET = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define kMaxHistorySize ((UInt32)3 << 29)
|
#define kLzmaMaxHistorySize ((UInt32)3 << 29)
|
||||||
/* #define kMaxHistorySize ((UInt32)7 << 29) */
|
/* #define kLzmaMaxHistorySize ((UInt32)7 << 29) */
|
||||||
|
|
||||||
#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
|
#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
|
||||||
|
|
||||||
@@ -62,14 +62,15 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
|
|||||||
if (level < 0) level = 5;
|
if (level < 0) level = 5;
|
||||||
p->level = level;
|
p->level = level;
|
||||||
|
|
||||||
if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
|
if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level <= 7 ? (1 << 25) : (1 << 26)));
|
||||||
if (p->dictSize > p->reduceSize)
|
if (p->dictSize > p->reduceSize)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
UInt32 reduceSize = (UInt32)p->reduceSize;
|
||||||
for (i = 11; i <= 30; i++)
|
for (i = 11; i <= 30; i++)
|
||||||
{
|
{
|
||||||
if ((UInt32)p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
|
if (reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
|
||||||
if ((UInt32)p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
|
if (reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +109,7 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
|
|||||||
|
|
||||||
#define kDicLogSizeMaxCompress 32
|
#define kDicLogSizeMaxCompress 32
|
||||||
|
|
||||||
#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
|
#define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); res = (zz + zz) + ((pos >> (zz - 1)) & 1); }
|
||||||
|
|
||||||
static UInt32 GetPosSlot1(UInt32 pos)
|
static UInt32 GetPosSlot1(UInt32 pos)
|
||||||
{
|
{
|
||||||
@@ -145,19 +146,19 @@ static void LzmaEnc_FastPosInit(Byte *g_FastPos)
|
|||||||
|
|
||||||
/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */
|
/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */
|
||||||
/*
|
/*
|
||||||
#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
|
#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \
|
||||||
(0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
|
(0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
|
||||||
res = p->g_FastPos[pos >> i] + (i * 2); }
|
res = p->g_FastPos[pos >> zz] + (zz * 2); }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
|
#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \
|
||||||
(0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \
|
(0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \
|
||||||
res = p->g_FastPos[pos >> i] + (i * 2); }
|
res = p->g_FastPos[pos >> zz] + (zz * 2); }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define BSR2_RET(pos, res) { UInt32 i = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
|
#define BSR2_RET(pos, res) { UInt32 zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
|
||||||
res = p->g_FastPos[pos >> i] + (i * 2); }
|
res = p->g_FastPos[pos >> zz] + (zz * 2); }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
|
#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
|
||||||
@@ -445,7 +446,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
|
|||||||
|| props.lp > LZMA_LP_MAX
|
|| props.lp > LZMA_LP_MAX
|
||||||
|| props.pb > LZMA_PB_MAX
|
|| props.pb > LZMA_PB_MAX
|
||||||
|| props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress)
|
|| props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress)
|
||||||
|| props.dictSize > kMaxHistorySize)
|
|| props.dictSize > kLzmaMaxHistorySize)
|
||||||
return SZ_ERROR_PARAM;
|
return SZ_ERROR_PARAM;
|
||||||
|
|
||||||
p->dictSize = props.dictSize;
|
p->dictSize = props.dictSize;
|
||||||
@@ -492,6 +493,15 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LzmaEnc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize)
|
||||||
|
{
|
||||||
|
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||||
|
p->matchFinderBase.expectedDataSize = expectedDataSiize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
|
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 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 kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
|
||||||
@@ -512,11 +522,11 @@ static void RangeEnc_Construct(CRangeEnc *p)
|
|||||||
#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 RC_BUF_SIZE (1 << 16)
|
#define RC_BUF_SIZE (1 << 16)
|
||||||
static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
|
static int RangeEnc_Alloc(CRangeEnc *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
if (!p->bufBase)
|
if (!p->bufBase)
|
||||||
{
|
{
|
||||||
p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
|
p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, RC_BUF_SIZE);
|
||||||
if (!p->bufBase)
|
if (!p->bufBase)
|
||||||
return 0;
|
return 0;
|
||||||
p->bufLim = p->bufBase + RC_BUF_SIZE;
|
p->bufLim = p->bufBase + RC_BUF_SIZE;
|
||||||
@@ -524,9 +534,9 @@ static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
|
static void RangeEnc_Free(CRangeEnc *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->bufBase);
|
ISzAlloc_Free(alloc, p->bufBase);
|
||||||
p->bufBase = 0;
|
p->bufBase = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,7 +560,7 @@ static void RangeEnc_FlushStream(CRangeEnc *p)
|
|||||||
if (p->res != SZ_OK)
|
if (p->res != SZ_OK)
|
||||||
return;
|
return;
|
||||||
num = p->buf - p->bufBase;
|
num = p->buf - p->bufBase;
|
||||||
if (num != p->outStream->Write(p->outStream, p->bufBase, num))
|
if (num != ISeqOutStream_Write(p->outStream, p->bufBase, num))
|
||||||
p->res = SZ_ERROR_WRITE;
|
p->res = SZ_ERROR_WRITE;
|
||||||
p->processed += num;
|
p->processed += num;
|
||||||
p->buf = p->bufBase;
|
p->buf = p->bufBase;
|
||||||
@@ -882,7 +892,7 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
|
|||||||
|
|
||||||
if (numPairs > 0)
|
if (numPairs > 0)
|
||||||
{
|
{
|
||||||
lenRes = p->matches[numPairs - 2];
|
lenRes = p->matches[(size_t)numPairs - 2];
|
||||||
if (lenRes == p->numFastBytes)
|
if (lenRes == p->numFastBytes)
|
||||||
{
|
{
|
||||||
UInt32 numAvail = p->numAvail;
|
UInt32 numAvail = p->numAvail;
|
||||||
@@ -891,7 +901,7 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
|
|||||||
{
|
{
|
||||||
const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
|
const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
|
||||||
const Byte *pby = pbyCur + lenRes;
|
const Byte *pby = pbyCur + lenRes;
|
||||||
ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[numPairs - 1];
|
ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[(size_t)numPairs - 1];
|
||||||
const Byte *pbyLim = pbyCur + numAvail;
|
const Byte *pbyLim = pbyCur + numAvail;
|
||||||
for (; pby != pbyLim && *pby == pby[dif]; pby++);
|
for (; pby != pbyLim && *pby == pby[dif]; pby++);
|
||||||
lenRes = (UInt32)(pby - pbyCur);
|
lenRes = (UInt32)(pby - pbyCur);
|
||||||
@@ -939,7 +949,7 @@ static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32
|
|||||||
|
|
||||||
static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
|
static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
|
||||||
{
|
{
|
||||||
return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
|
return p->repLenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN] +
|
||||||
GetPureRepPrice(p, repIndex, state, posState);
|
GetPureRepPrice(p, repIndex, state, posState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -956,9 +966,9 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
|
|||||||
p->opt[posMem].posPrev = posMem - 1;
|
p->opt[posMem].posPrev = posMem - 1;
|
||||||
if (p->opt[cur].prev2)
|
if (p->opt[cur].prev2)
|
||||||
{
|
{
|
||||||
p->opt[posMem - 1].prev1IsChar = False;
|
p->opt[(size_t)posMem - 1].prev1IsChar = False;
|
||||||
p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
|
p->opt[(size_t)posMem - 1].posPrev = p->opt[cur].posPrev2;
|
||||||
p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
|
p->opt[(size_t)posMem - 1].backPrev = p->opt[cur].backPrev2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@@ -983,12 +993,17 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
|
|||||||
|
|
||||||
static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
||||||
{
|
{
|
||||||
UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur;
|
UInt32 lenEnd, cur;
|
||||||
UInt32 matchPrice, repMatchPrice, normalMatchPrice;
|
|
||||||
UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
|
UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
|
||||||
UInt32 *matches;
|
UInt32 *matches;
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, len;
|
||||||
|
UInt32 matchPrice, repMatchPrice, normalMatchPrice;
|
||||||
const Byte *data;
|
const Byte *data;
|
||||||
Byte curByte, matchByte;
|
Byte curByte, matchByte;
|
||||||
|
|
||||||
if (p->optimumEndIndex != p->optimumCurrentIndex)
|
if (p->optimumEndIndex != p->optimumCurrentIndex)
|
||||||
{
|
{
|
||||||
const COptimal *opt = &p->opt[p->optimumCurrentIndex];
|
const COptimal *opt = &p->opt[p->optimumCurrentIndex];
|
||||||
@@ -1046,7 +1061,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
matches = p->matches;
|
matches = p->matches;
|
||||||
if (mainLen >= p->numFastBytes)
|
if (mainLen >= p->numFastBytes)
|
||||||
{
|
{
|
||||||
*backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
|
*backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
|
||||||
MovePos(p, mainLen - 1);
|
MovePos(p, mainLen - 1);
|
||||||
return mainLen;
|
return mainLen;
|
||||||
}
|
}
|
||||||
@@ -1111,7 +1126,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
|
price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
|
UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][(size_t)repLen - 2];
|
||||||
COptimal *opt = &p->opt[repLen];
|
COptimal *opt = &p->opt[repLen];
|
||||||
if (curAndLenPrice < opt->price)
|
if (curAndLenPrice < opt->price)
|
||||||
{
|
{
|
||||||
@@ -1135,9 +1150,9 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
for (; ; len++)
|
for (; ; len++)
|
||||||
{
|
{
|
||||||
COptimal *opt;
|
COptimal *opt;
|
||||||
UInt32 distance = matches[offs + 1];
|
UInt32 distance = matches[(size_t)offs + 1];
|
||||||
|
|
||||||
UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
|
UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN];
|
||||||
UInt32 lenToPosState = GetLenToPosState(len);
|
UInt32 lenToPosState = GetLenToPosState(len);
|
||||||
if (distance < kNumFullDistances)
|
if (distance < kNumFullDistances)
|
||||||
curAndLenPrice += p->distancesPrices[lenToPosState][distance];
|
curAndLenPrice += p->distancesPrices[lenToPosState][distance];
|
||||||
@@ -1176,8 +1191,11 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
UInt32 numAvail;
|
||||||
UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
|
UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
|
||||||
UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
|
UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
|
||||||
Bool nextIsChar;
|
Bool nextIsChar;
|
||||||
@@ -1248,7 +1266,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
UInt32 i;
|
UInt32 i;
|
||||||
reps[0] = prevOpt->backs[pos];
|
reps[0] = prevOpt->backs[pos];
|
||||||
for (i = 1; i <= pos; i++)
|
for (i = 1; i <= pos; i++)
|
||||||
reps[i] = prevOpt->backs[i - 1];
|
reps[i] = prevOpt->backs[(size_t)i - 1];
|
||||||
for (; i < LZMA_NUM_REPS; i++)
|
for (; i < LZMA_NUM_REPS; i++)
|
||||||
reps[i] = prevOpt->backs[i];
|
reps[i] = prevOpt->backs[i];
|
||||||
}
|
}
|
||||||
@@ -1257,7 +1275,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
UInt32 i;
|
UInt32 i;
|
||||||
reps[0] = (pos - LZMA_NUM_REPS);
|
reps[0] = (pos - LZMA_NUM_REPS);
|
||||||
for (i = 1; i < LZMA_NUM_REPS; i++)
|
for (i = 1; i < LZMA_NUM_REPS; i++)
|
||||||
reps[i] = prevOpt->backs[i - 1];
|
reps[i] = prevOpt->backs[(size_t)i - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
curOpt->state = (CState)state;
|
curOpt->state = (CState)state;
|
||||||
@@ -1284,7 +1302,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
LitEnc_GetPrice(probs, curByte, p->ProbPrices));
|
LitEnc_GetPrice(probs, curByte, p->ProbPrices));
|
||||||
}
|
}
|
||||||
|
|
||||||
nextOpt = &p->opt[cur + 1];
|
nextOpt = &p->opt[(size_t)cur + 1];
|
||||||
|
|
||||||
if (curAnd1Price < nextOpt->price)
|
if (curAnd1Price < nextOpt->price)
|
||||||
{
|
{
|
||||||
@@ -1377,7 +1395,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
|
price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
|
UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][(size_t)lenTest - 2];
|
||||||
COptimal *opt = &p->opt[cur + lenTest];
|
COptimal *opt = &p->opt[cur + lenTest];
|
||||||
if (curAndLenPrice < opt->price)
|
if (curAndLenPrice < opt->price)
|
||||||
{
|
{
|
||||||
@@ -1407,9 +1425,9 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
UInt32 state2 = kRepNextStates[state];
|
UInt32 state2 = kRepNextStates[state];
|
||||||
UInt32 posStateNext = (position + lenTest) & p->pbMask;
|
UInt32 posStateNext = (position + lenTest) & p->pbMask;
|
||||||
UInt32 curAndLenCharPrice =
|
UInt32 curAndLenCharPrice =
|
||||||
price + p->repLenEnc.prices[posState][lenTest - 2] +
|
price + p->repLenEnc.prices[posState][(size_t)lenTest - 2] +
|
||||||
GET_PRICE_0(p->isMatch[state2][posStateNext]) +
|
GET_PRICE_0(p->isMatch[state2][posStateNext]) +
|
||||||
LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
|
LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[(size_t)lenTest - 1]),
|
||||||
data[lenTest], data2[lenTest], p->ProbPrices);
|
data[lenTest], data2[lenTest], p->ProbPrices);
|
||||||
state2 = kLiteralNextStates[state2];
|
state2 = kLiteralNextStates[state2];
|
||||||
posStateNext = (position + lenTest + 1) & p->pbMask;
|
posStateNext = (position + lenTest + 1) & p->pbMask;
|
||||||
@@ -1460,11 +1478,12 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
offs = 0;
|
offs = 0;
|
||||||
while (startLen > matches[offs])
|
while (startLen > matches[offs])
|
||||||
offs += 2;
|
offs += 2;
|
||||||
curBack = matches[offs + 1];
|
curBack = matches[(size_t)offs + 1];
|
||||||
GetPosSlot2(curBack, posSlot);
|
GetPosSlot2(curBack, posSlot);
|
||||||
for (lenTest = /*2*/ startLen; ; lenTest++)
|
for (lenTest = /*2*/ startLen; ; lenTest++)
|
||||||
{
|
{
|
||||||
UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
|
UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][(size_t)lenTest - LZMA_MATCH_LEN_MIN];
|
||||||
|
{
|
||||||
UInt32 lenToPosState = GetLenToPosState(lenTest);
|
UInt32 lenToPosState = GetLenToPosState(lenTest);
|
||||||
COptimal *opt;
|
COptimal *opt;
|
||||||
if (curBack < kNumFullDistances)
|
if (curBack < kNumFullDistances)
|
||||||
@@ -1480,6 +1499,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
opt->backPrev = curBack + LZMA_NUM_REPS;
|
opt->backPrev = curBack + LZMA_NUM_REPS;
|
||||||
opt->prev1IsChar = False;
|
opt->prev1IsChar = False;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (/*_maxMode && */lenTest == matches[offs])
|
if (/*_maxMode && */lenTest == matches[offs])
|
||||||
{
|
{
|
||||||
@@ -1498,7 +1518,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
UInt32 posStateNext = (position + lenTest) & p->pbMask;
|
UInt32 posStateNext = (position + lenTest) & p->pbMask;
|
||||||
UInt32 curAndLenCharPrice = curAndLenPrice +
|
UInt32 curAndLenCharPrice = curAndLenPrice +
|
||||||
GET_PRICE_0(p->isMatch[state2][posStateNext]) +
|
GET_PRICE_0(p->isMatch[state2][posStateNext]) +
|
||||||
LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
|
LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[(size_t)lenTest - 1]),
|
||||||
data[lenTest], data2[lenTest], p->ProbPrices);
|
data[lenTest], data2[lenTest], p->ProbPrices);
|
||||||
state2 = kLiteralNextStates[state2];
|
state2 = kLiteralNextStates[state2];
|
||||||
posStateNext = (posStateNext + 1) & p->pbMask;
|
posStateNext = (posStateNext + 1) & p->pbMask;
|
||||||
@@ -1509,15 +1529,15 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
/* for (; lenTest2 >= 2; lenTest2--) */
|
/* for (; lenTest2 >= 2; lenTest2--) */
|
||||||
{
|
{
|
||||||
UInt32 offset = cur + lenTest + 1 + lenTest2;
|
UInt32 offset = cur + lenTest + 1 + lenTest2;
|
||||||
UInt32 curAndLenPrice;
|
UInt32 curAndLenPrice2;
|
||||||
COptimal *opt;
|
COptimal *opt;
|
||||||
while (lenEnd < offset)
|
while (lenEnd < offset)
|
||||||
p->opt[++lenEnd].price = kInfinityPrice;
|
p->opt[++lenEnd].price = kInfinityPrice;
|
||||||
curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
|
curAndLenPrice2 = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
|
||||||
opt = &p->opt[offset];
|
opt = &p->opt[offset];
|
||||||
if (curAndLenPrice < opt->price)
|
if (curAndLenPrice2 < opt->price)
|
||||||
{
|
{
|
||||||
opt->price = curAndLenPrice;
|
opt->price = curAndLenPrice2;
|
||||||
opt->posPrev = cur + lenTest + 1;
|
opt->posPrev = cur + lenTest + 1;
|
||||||
opt->backPrev = 0;
|
opt->backPrev = 0;
|
||||||
opt->prev1IsChar = True;
|
opt->prev1IsChar = True;
|
||||||
@@ -1530,7 +1550,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
offs += 2;
|
offs += 2;
|
||||||
if (offs == numPairs)
|
if (offs == numPairs)
|
||||||
break;
|
break;
|
||||||
curBack = matches[offs + 1];
|
curBack = matches[(size_t)offs + 1];
|
||||||
if (curBack >= kNumFullDistances)
|
if (curBack >= kNumFullDistances)
|
||||||
GetPosSlot2(curBack, posSlot);
|
GetPosSlot2(curBack, posSlot);
|
||||||
}
|
}
|
||||||
@@ -1587,7 +1607,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
|
|||||||
matches = p->matches;
|
matches = p->matches;
|
||||||
if (mainLen >= p->numFastBytes)
|
if (mainLen >= p->numFastBytes)
|
||||||
{
|
{
|
||||||
*backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
|
*backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
|
||||||
MovePos(p, mainLen - 1);
|
MovePos(p, mainLen - 1);
|
||||||
return mainLen;
|
return mainLen;
|
||||||
}
|
}
|
||||||
@@ -1595,14 +1615,14 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
|
|||||||
mainDist = 0; /* for GCC */
|
mainDist = 0; /* for GCC */
|
||||||
if (mainLen >= 2)
|
if (mainLen >= 2)
|
||||||
{
|
{
|
||||||
mainDist = matches[numPairs - 1];
|
mainDist = matches[(size_t)numPairs - 1];
|
||||||
while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)
|
while (numPairs > 2 && mainLen == matches[(size_t)numPairs - 4] + 1)
|
||||||
{
|
{
|
||||||
if (!ChangePair(matches[numPairs - 3], mainDist))
|
if (!ChangePair(matches[(size_t)numPairs - 3], mainDist))
|
||||||
break;
|
break;
|
||||||
numPairs -= 2;
|
numPairs -= 2;
|
||||||
mainLen = matches[numPairs - 2];
|
mainLen = matches[(size_t)numPairs - 2];
|
||||||
mainDist = matches[numPairs - 1];
|
mainDist = matches[(size_t)numPairs - 1];
|
||||||
}
|
}
|
||||||
if (mainLen == 2 && mainDist >= 0x80)
|
if (mainLen == 2 && mainDist >= 0x80)
|
||||||
mainLen = 1;
|
mainLen = 1;
|
||||||
@@ -1624,7 +1644,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
|
|||||||
p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
|
p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
|
||||||
if (p->longestMatchLength >= 2)
|
if (p->longestMatchLength >= 2)
|
||||||
{
|
{
|
||||||
UInt32 newDistance = matches[p->numPairs - 1];
|
UInt32 newDistance = matches[(size_t)p->numPairs - 1];
|
||||||
if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
|
if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
|
||||||
(p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
|
(p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
|
||||||
(p->longestMatchLength > mainLen + 1) ||
|
(p->longestMatchLength > mainLen + 1) ||
|
||||||
@@ -1718,7 +1738,6 @@ static void FillDistancesPrices(CLzmaEnc *p)
|
|||||||
|
|
||||||
{
|
{
|
||||||
UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
|
UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
|
||||||
UInt32 i;
|
|
||||||
for (i = 0; i < kStartPosModelIndex; i++)
|
for (i = 0; i < kStartPosModelIndex; i++)
|
||||||
distancesPrices[i] = posSlotPrices[i];
|
distancesPrices[i] = posSlotPrices[i];
|
||||||
for (; i < kNumFullDistances; i++)
|
for (; i < kNumFullDistances; i++)
|
||||||
@@ -1753,24 +1772,24 @@ void LzmaEnc_Construct(CLzmaEnc *p)
|
|||||||
p->saveState.litProbs = NULL;
|
p->saveState.litProbs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
|
CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
|
p = ISzAlloc_Alloc(alloc, sizeof(CLzmaEnc));
|
||||||
if (p)
|
if (p)
|
||||||
LzmaEnc_Construct((CLzmaEnc *)p);
|
LzmaEnc_Construct((CLzmaEnc *)p);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
|
void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->litProbs);
|
ISzAlloc_Free(alloc, p->litProbs);
|
||||||
alloc->Free(alloc, p->saveState.litProbs);
|
ISzAlloc_Free(alloc, p->saveState.litProbs);
|
||||||
p->litProbs = NULL;
|
p->litProbs = NULL;
|
||||||
p->saveState.litProbs = NULL;
|
p->saveState.litProbs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
|
void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
||||||
{
|
{
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
|
MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
|
||||||
@@ -1781,10 +1800,10 @@ void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
|
|||||||
RangeEnc_Free(&p->rc, alloc);
|
RangeEnc_Free(&p->rc, alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
|
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
||||||
{
|
{
|
||||||
LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
|
LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
|
||||||
alloc->Free(alloc, p);
|
ISzAlloc_Free(alloc, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
|
static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
|
||||||
@@ -1951,7 +1970,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
|
|||||||
|
|
||||||
#define kBigHashDicLimit ((UInt32)1 << 24)
|
#define kBigHashDicLimit ((UInt32)1 << 24)
|
||||||
|
|
||||||
static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
|
static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
||||||
{
|
{
|
||||||
UInt32 beforeSize = kNumOpts;
|
UInt32 beforeSize = kNumOpts;
|
||||||
if (!RangeEnc_Alloc(&p->rc, alloc))
|
if (!RangeEnc_Alloc(&p->rc, alloc))
|
||||||
@@ -1966,8 +1985,8 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
|
|||||||
if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp)
|
if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp)
|
||||||
{
|
{
|
||||||
LzmaEnc_FreeLits(p, alloc);
|
LzmaEnc_FreeLits(p, alloc);
|
||||||
p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
|
p->litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
|
||||||
p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
|
p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
|
||||||
if (!p->litProbs || !p->saveState.litProbs)
|
if (!p->litProbs || !p->saveState.litProbs)
|
||||||
{
|
{
|
||||||
LzmaEnc_FreeLits(p, alloc);
|
LzmaEnc_FreeLits(p, alloc);
|
||||||
@@ -1987,6 +2006,8 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
|
|||||||
{
|
{
|
||||||
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, allocBig));
|
||||||
p->matchFinderObj = &p->matchFinderMt;
|
p->matchFinderObj = &p->matchFinderMt;
|
||||||
|
p->matchFinderBase.bigHash = (Byte)(
|
||||||
|
(p->dictSize > kBigHashDicLimit && p->matchFinderBase.hashMask >= 0xFFFFFF) ? 1 : 0);
|
||||||
MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
|
MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2075,7 +2096,7 @@ void LzmaEnc_InitPrices(CLzmaEnc *p)
|
|||||||
LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
|
LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
|
static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
|
for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
|
||||||
@@ -2093,7 +2114,7 @@ static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *a
|
|||||||
}
|
}
|
||||||
|
|
||||||
static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,
|
static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||||
ISzAlloc *alloc, ISzAlloc *allocBig)
|
ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
||||||
{
|
{
|
||||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||||
p->matchFinderBase.stream = inStream;
|
p->matchFinderBase.stream = inStream;
|
||||||
@@ -2104,7 +2125,7 @@ static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInS
|
|||||||
|
|
||||||
SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
|
SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
|
||||||
ISeqInStream *inStream, UInt32 keepWindowSize,
|
ISeqInStream *inStream, UInt32 keepWindowSize,
|
||||||
ISzAlloc *alloc, ISzAlloc *allocBig)
|
ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
||||||
{
|
{
|
||||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||||
p->matchFinderBase.stream = inStream;
|
p->matchFinderBase.stream = inStream;
|
||||||
@@ -2120,12 +2141,13 @@ static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
|
SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
|
||||||
UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
|
UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
||||||
{
|
{
|
||||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||||
LzmaEnc_SetInputBuf(p, src, srcLen);
|
LzmaEnc_SetInputBuf(p, src, srcLen);
|
||||||
p->needInit = 1;
|
p->needInit = 1;
|
||||||
|
|
||||||
|
LzmaEnc_SetDataSize(pp, srcLen);
|
||||||
return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
|
return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2143,15 +2165,15 @@ void LzmaEnc_Finish(CLzmaEncHandle pp)
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ISeqOutStream funcTable;
|
ISeqOutStream vt;
|
||||||
Byte *data;
|
Byte *data;
|
||||||
SizeT rem;
|
SizeT rem;
|
||||||
Bool overflow;
|
Bool overflow;
|
||||||
} CSeqOutStreamBuf;
|
} CLzmaEnc_SeqOutStreamBuf;
|
||||||
|
|
||||||
static size_t MyWrite(void *pp, const void *data, size_t size)
|
static size_t SeqOutStreamBuf_Write(const ISeqOutStream *pp, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
|
CLzmaEnc_SeqOutStreamBuf *p = CONTAINER_FROM_VTBL(pp, CLzmaEnc_SeqOutStreamBuf, vt);
|
||||||
if (p->rem < size)
|
if (p->rem < size)
|
||||||
{
|
{
|
||||||
size = p->rem;
|
size = p->rem;
|
||||||
@@ -2184,9 +2206,9 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
|
|||||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||||
UInt64 nowPos64;
|
UInt64 nowPos64;
|
||||||
SRes res;
|
SRes res;
|
||||||
CSeqOutStreamBuf outStream;
|
CLzmaEnc_SeqOutStreamBuf outStream;
|
||||||
|
|
||||||
outStream.funcTable.Write = MyWrite;
|
outStream.vt.Write = SeqOutStreamBuf_Write;
|
||||||
outStream.data = dest;
|
outStream.data = dest;
|
||||||
outStream.rem = *destLen;
|
outStream.rem = *destLen;
|
||||||
outStream.overflow = False;
|
outStream.overflow = False;
|
||||||
@@ -2200,7 +2222,7 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
|
|||||||
LzmaEnc_InitPrices(p);
|
LzmaEnc_InitPrices(p);
|
||||||
nowPos64 = p->nowPos64;
|
nowPos64 = p->nowPos64;
|
||||||
RangeEnc_Init(&p->rc);
|
RangeEnc_Init(&p->rc);
|
||||||
p->rc.outStream = &outStream.funcTable;
|
p->rc.outStream = &outStream.vt;
|
||||||
|
|
||||||
res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
|
res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
|
||||||
|
|
||||||
@@ -2230,7 +2252,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
|
|||||||
break;
|
break;
|
||||||
if (progress)
|
if (progress)
|
||||||
{
|
{
|
||||||
res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
|
res = ICompressProgress_Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
{
|
{
|
||||||
res = SZ_ERROR_PROGRESS;
|
res = SZ_ERROR_PROGRESS;
|
||||||
@@ -2242,7 +2264,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
|
|||||||
LzmaEnc_Finish(p);
|
LzmaEnc_Finish(p);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (res == S_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
|
if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
|
||||||
res = SZ_ERROR_FAIL;
|
res = SZ_ERROR_FAIL;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@@ -2252,7 +2274,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
|
|||||||
|
|
||||||
|
|
||||||
SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
|
SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
|
||||||
ISzAlloc *alloc, ISzAlloc *allocBig)
|
ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
||||||
{
|
{
|
||||||
RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));
|
RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));
|
||||||
return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
|
return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
|
||||||
@@ -2287,21 +2309,27 @@ SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle pp)
|
||||||
|
{
|
||||||
|
return ((CLzmaEnc *)pp)->writeEndMark;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||||
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
|
int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
||||||
{
|
{
|
||||||
SRes res;
|
SRes res;
|
||||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||||
|
|
||||||
CSeqOutStreamBuf outStream;
|
CLzmaEnc_SeqOutStreamBuf outStream;
|
||||||
|
|
||||||
outStream.funcTable.Write = MyWrite;
|
outStream.vt.Write = SeqOutStreamBuf_Write;
|
||||||
outStream.data = dest;
|
outStream.data = dest;
|
||||||
outStream.rem = *destLen;
|
outStream.rem = *destLen;
|
||||||
outStream.overflow = False;
|
outStream.overflow = False;
|
||||||
|
|
||||||
p->writeEndMark = writeEndMark;
|
p->writeEndMark = writeEndMark;
|
||||||
p->rc.outStream = &outStream.funcTable;
|
p->rc.outStream = &outStream.vt;
|
||||||
|
|
||||||
res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
|
res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
|
||||||
|
|
||||||
@@ -2321,7 +2349,7 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
|
|||||||
|
|
||||||
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||||
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
|
ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
||||||
{
|
{
|
||||||
CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
|
CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
|
||||||
SRes res;
|
SRes res;
|
||||||
|
|||||||
48
C/LzmaEnc.h
48
C/LzmaEnc.h
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaEnc.h -- LZMA Encoder
|
/* LzmaEnc.h -- LZMA Encoder
|
||||||
2013-01-18 : Igor Pavlov : Public domain */
|
2017-07-27 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZMA_ENC_H
|
#ifndef __LZMA_ENC_H
|
||||||
#define __LZMA_ENC_H
|
#define __LZMA_ENC_H
|
||||||
@@ -12,12 +12,10 @@ EXTERN_C_BEGIN
|
|||||||
|
|
||||||
typedef struct _CLzmaEncProps
|
typedef struct _CLzmaEncProps
|
||||||
{
|
{
|
||||||
int level; /* 0 <= level <= 9 */
|
int level; /* 0 <= level <= 9 */
|
||||||
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
|
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
|
||||||
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
|
(1 << 12) <= dictSize <= (3 << 29) for 64-bit version
|
||||||
default = (1 << 24) */
|
default = (1 << 24) */
|
||||||
UInt64 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF.
|
|
||||||
Encoder uses this value to reduce dictionary size */
|
|
||||||
int lc; /* 0 <= lc <= 8, default = 3 */
|
int lc; /* 0 <= lc <= 8, default = 3 */
|
||||||
int lp; /* 0 <= lp <= 4, default = 0 */
|
int lp; /* 0 <= lp <= 4, default = 0 */
|
||||||
int pb; /* 0 <= pb <= 4, default = 2 */
|
int pb; /* 0 <= pb <= 4, default = 2 */
|
||||||
@@ -25,9 +23,12 @@ typedef struct _CLzmaEncProps
|
|||||||
int fb; /* 5 <= fb <= 273, default = 32 */
|
int fb; /* 5 <= fb <= 273, default = 32 */
|
||||||
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
|
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
|
||||||
int numHashBytes; /* 2, 3 or 4, default = 4 */
|
int numHashBytes; /* 2, 3 or 4, default = 4 */
|
||||||
UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
|
UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
|
||||||
unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
|
unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
|
||||||
int numThreads; /* 1 or 2, default = 2 */
|
int numThreads; /* 1 or 2, default = 2 */
|
||||||
|
|
||||||
|
UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1.
|
||||||
|
Encoder uses this value to reduce dictionary size */
|
||||||
} CLzmaEncProps;
|
} CLzmaEncProps;
|
||||||
|
|
||||||
void LzmaEncProps_Init(CLzmaEncProps *p);
|
void LzmaEncProps_Init(CLzmaEncProps *p);
|
||||||
@@ -37,41 +38,38 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
|
|||||||
|
|
||||||
/* ---------- CLzmaEncHandle Interface ---------- */
|
/* ---------- CLzmaEncHandle Interface ---------- */
|
||||||
|
|
||||||
/* LzmaEnc_* functions can return the following exit codes:
|
/* LzmaEnc* functions can return the following exit codes:
|
||||||
Returns:
|
SRes:
|
||||||
SZ_OK - OK
|
SZ_OK - OK
|
||||||
SZ_ERROR_MEM - Memory allocation error
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
SZ_ERROR_PARAM - Incorrect paramater in props
|
SZ_ERROR_PARAM - Incorrect paramater in props
|
||||||
SZ_ERROR_WRITE - Write callback error.
|
SZ_ERROR_WRITE - ISeqOutStream write callback error
|
||||||
|
SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
|
||||||
SZ_ERROR_PROGRESS - some break from progress callback
|
SZ_ERROR_PROGRESS - some break from progress callback
|
||||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef void * CLzmaEncHandle;
|
typedef void * CLzmaEncHandle;
|
||||||
|
|
||||||
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
|
CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc);
|
||||||
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
|
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
||||||
|
|
||||||
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
|
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
|
||||||
|
void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize);
|
||||||
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
|
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
|
||||||
|
unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p);
|
||||||
|
|
||||||
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
|
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
||||||
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||||
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
||||||
|
|
||||||
|
|
||||||
/* ---------- One Call Interface ---------- */
|
/* ---------- One Call Interface ---------- */
|
||||||
|
|
||||||
/* LzmaEncode
|
|
||||||
Return code:
|
|
||||||
SZ_OK - OK
|
|
||||||
SZ_ERROR_MEM - Memory allocation error
|
|
||||||
SZ_ERROR_PARAM - Incorrect paramater
|
|
||||||
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
|
||||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
|
||||||
*/
|
|
||||||
|
|
||||||
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||||
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
|
|||||||
745
C/MtCoder.c
745
C/MtCoder.c
@@ -1,95 +1,72 @@
|
|||||||
/* MtCoder.c -- Multi-thread Coder
|
/* MtCoder.c -- Multi-thread Coder
|
||||||
2015-10-13 : Igor Pavlov : Public domain */
|
2017-07-17 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include "MtCoder.h"
|
#include "MtCoder.h"
|
||||||
|
|
||||||
void LoopThread_Construct(CLoopThread *p)
|
|
||||||
{
|
|
||||||
Thread_Construct(&p->thread);
|
|
||||||
Event_Construct(&p->startEvent);
|
|
||||||
Event_Construct(&p->finishedEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoopThread_Close(CLoopThread *p)
|
|
||||||
{
|
|
||||||
Thread_Close(&p->thread);
|
|
||||||
Event_Close(&p->startEvent);
|
|
||||||
Event_Close(&p->finishedEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE LoopThreadFunc(void *pp)
|
|
||||||
{
|
|
||||||
CLoopThread *p = (CLoopThread *)pp;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
if (Event_Wait(&p->startEvent) != 0)
|
|
||||||
return SZ_ERROR_THREAD;
|
|
||||||
if (p->stop)
|
|
||||||
return 0;
|
|
||||||
p->res = p->func(p->param);
|
|
||||||
if (Event_Set(&p->finishedEvent) != 0)
|
|
||||||
return SZ_ERROR_THREAD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WRes LoopThread_Create(CLoopThread *p)
|
|
||||||
{
|
|
||||||
p->stop = 0;
|
|
||||||
RINOK(AutoResetEvent_CreateNotSignaled(&p->startEvent));
|
|
||||||
RINOK(AutoResetEvent_CreateNotSignaled(&p->finishedEvent));
|
|
||||||
return Thread_Create(&p->thread, LoopThreadFunc, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
WRes LoopThread_StopAndWait(CLoopThread *p)
|
|
||||||
{
|
|
||||||
p->stop = 1;
|
|
||||||
if (Event_Set(&p->startEvent) != 0)
|
|
||||||
return SZ_ERROR_THREAD;
|
|
||||||
return Thread_Wait(&p->thread);
|
|
||||||
}
|
|
||||||
|
|
||||||
WRes LoopThread_StartSubThread(CLoopThread *p) { return Event_Set(&p->startEvent); }
|
|
||||||
WRes LoopThread_WaitSubThread(CLoopThread *p) { return Event_Wait(&p->finishedEvent); }
|
|
||||||
|
|
||||||
static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
|
|
||||||
{
|
|
||||||
return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void MtProgress_Init(CMtProgress *p, ICompressProgress *progress)
|
static void MtProgress_Init(CMtProgress *p, ICompressProgress *progress)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
|
|
||||||
p->inSizes[i] = p->outSizes[i] = 0;
|
|
||||||
p->totalInSize = p->totalOutSize = 0;
|
|
||||||
p->progress = progress;
|
p->progress = progress;
|
||||||
p->res = SZ_OK;
|
p->res = SZ_OK;
|
||||||
|
p->totalInSize = 0;
|
||||||
|
p->totalOutSize = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < MTCODER__THREADS_MAX; i++)
|
||||||
|
{
|
||||||
|
CMtProgressSizes *pair = &p->sizes[i];
|
||||||
|
pair->inSize = 0;
|
||||||
|
pair->outSize = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void MtProgress_Reinit(CMtProgress *p, unsigned index)
|
static void MtProgress_Reinit(CMtProgress *p, unsigned index)
|
||||||
{
|
{
|
||||||
p->inSizes[index] = 0;
|
CMtProgressSizes *pair = &p->sizes[index];
|
||||||
p->outSizes[index] = 0;
|
pair->inSize = 0;
|
||||||
|
pair->outSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define UPDATE_PROGRESS(size, prev, total) \
|
#define UPDATE_PROGRESS(size, prev, total) \
|
||||||
if (size != (UInt64)(Int64)-1) { total += size - prev; prev = size; }
|
if (size != (UInt64)(Int64)-1) { total += size - prev; prev = size; }
|
||||||
|
|
||||||
SRes MtProgress_Set(CMtProgress *p, unsigned index, UInt64 inSize, UInt64 outSize)
|
SRes MtProgress_Set(CMtProgress *p, unsigned index, UInt64 inSize, UInt64 outSize)
|
||||||
|
{
|
||||||
|
SRes res;
|
||||||
|
CMtProgressSizes *pair;
|
||||||
|
|
||||||
|
CriticalSection_Enter(&p->cs);
|
||||||
|
|
||||||
|
pair = &p->sizes[index];
|
||||||
|
UPDATE_PROGRESS(inSize, pair->inSize, p->totalInSize)
|
||||||
|
UPDATE_PROGRESS(outSize, pair->outSize, p->totalOutSize)
|
||||||
|
if (p->res == SZ_OK && p->progress)
|
||||||
|
{
|
||||||
|
if (ICompressProgress_Progress(p->progress, p->totalInSize, p->totalOutSize) != SZ_OK)
|
||||||
|
p->res = SZ_ERROR_PROGRESS;
|
||||||
|
}
|
||||||
|
res = p->res;
|
||||||
|
|
||||||
|
CriticalSection_Leave(&p->cs);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static SRes MtProgress_GetError(CMtProgress *p)
|
||||||
{
|
{
|
||||||
SRes res;
|
SRes res;
|
||||||
CriticalSection_Enter(&p->cs);
|
CriticalSection_Enter(&p->cs);
|
||||||
UPDATE_PROGRESS(inSize, p->inSizes[index], p->totalInSize)
|
|
||||||
UPDATE_PROGRESS(outSize, p->outSizes[index], p->totalOutSize)
|
|
||||||
if (p->res == SZ_OK)
|
|
||||||
p->res = Progress(p->progress, p->totalInSize, p->totalOutSize);
|
|
||||||
res = p->res;
|
res = p->res;
|
||||||
CriticalSection_Leave(&p->cs);
|
CriticalSection_Leave(&p->cs);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void MtProgress_SetError(CMtProgress *p, SRes res)
|
static void MtProgress_SetError(CMtProgress *p, SRes res)
|
||||||
{
|
{
|
||||||
CriticalSection_Enter(&p->cs);
|
CriticalSection_Enter(&p->cs);
|
||||||
@@ -98,71 +75,72 @@ static void MtProgress_SetError(CMtProgress *p, SRes res)
|
|||||||
CriticalSection_Leave(&p->cs);
|
CriticalSection_Leave(&p->cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MtCoder_SetError(CMtCoder* p, SRes res)
|
|
||||||
|
static SRes MtProgressThunk_Progress(const ICompressProgress *pp, UInt64 inSize, UInt64 outSize)
|
||||||
{
|
{
|
||||||
CriticalSection_Enter(&p->cs);
|
CMtProgressThunk *p = CONTAINER_FROM_VTBL(pp, CMtProgressThunk, vt);
|
||||||
if (p->res == SZ_OK)
|
return MtProgress_Set(p->mtProgress, p->index, inSize, outSize);
|
||||||
p->res = res;
|
|
||||||
CriticalSection_Leave(&p->cs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- MtThread ---------- */
|
|
||||||
|
|
||||||
void CMtThread_Construct(CMtThread *p, CMtCoder *mtCoder)
|
void MtProgressThunk_CreateVTable(CMtProgressThunk *p)
|
||||||
{
|
{
|
||||||
p->mtCoder = mtCoder;
|
p->vt.Progress = MtProgressThunk_Progress;
|
||||||
p->outBuf = 0;
|
|
||||||
p->inBuf = 0;
|
|
||||||
Event_Construct(&p->canRead);
|
|
||||||
Event_Construct(&p->canWrite);
|
|
||||||
LoopThread_Construct(&p->thread);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
|
#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
|
||||||
|
|
||||||
static void CMtThread_CloseEvents(CMtThread *p)
|
|
||||||
|
static WRes ArEvent_OptCreate_And_Reset(CEvent *p)
|
||||||
{
|
{
|
||||||
Event_Close(&p->canRead);
|
if (Event_IsCreated(p))
|
||||||
Event_Close(&p->canWrite);
|
return Event_Reset(p);
|
||||||
|
return AutoResetEvent_CreateNotSignaled(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CMtThread_Destruct(CMtThread *p)
|
|
||||||
{
|
|
||||||
CMtThread_CloseEvents(p);
|
|
||||||
|
|
||||||
if (Thread_WasCreated(&p->thread.thread))
|
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE ThreadFunc(void *pp);
|
||||||
|
|
||||||
|
|
||||||
|
static SRes MtCoderThread_CreateAndStart(CMtCoderThread *t)
|
||||||
|
{
|
||||||
|
WRes wres = ArEvent_OptCreate_And_Reset(&t->startEvent);
|
||||||
|
if (wres == 0)
|
||||||
{
|
{
|
||||||
LoopThread_StopAndWait(&p->thread);
|
t->stop = False;
|
||||||
LoopThread_Close(&p->thread);
|
if (!Thread_WasCreated(&t->thread))
|
||||||
|
wres = Thread_Create(&t->thread, ThreadFunc, t);
|
||||||
|
if (wres == 0)
|
||||||
|
wres = Event_Set(&t->startEvent);
|
||||||
|
}
|
||||||
|
if (wres == 0)
|
||||||
|
return SZ_OK;
|
||||||
|
return MY_SRes_HRESULT_FROM_WRes(wres);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void MtCoderThread_Destruct(CMtCoderThread *t)
|
||||||
|
{
|
||||||
|
if (Thread_WasCreated(&t->thread))
|
||||||
|
{
|
||||||
|
t->stop = 1;
|
||||||
|
Event_Set(&t->startEvent);
|
||||||
|
Thread_Wait(&t->thread);
|
||||||
|
Thread_Close(&t->thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->mtCoder->alloc)
|
Event_Close(&t->startEvent);
|
||||||
IAlloc_Free(p->mtCoder->alloc, p->outBuf);
|
|
||||||
p->outBuf = 0;
|
|
||||||
|
|
||||||
if (p->mtCoder->alloc)
|
if (t->inBuf)
|
||||||
IAlloc_Free(p->mtCoder->alloc, p->inBuf);
|
{
|
||||||
p->inBuf = 0;
|
ISzAlloc_Free(t->mtCoder->allocBig, t->inBuf);
|
||||||
|
t->inBuf = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MY_BUF_ALLOC(buf, size, newSize) \
|
|
||||||
if (buf == 0 || size != newSize) \
|
|
||||||
{ IAlloc_Free(p->mtCoder->alloc, buf); \
|
|
||||||
size = newSize; buf = (Byte *)IAlloc_Alloc(p->mtCoder->alloc, size); \
|
|
||||||
if (buf == 0) return SZ_ERROR_MEM; }
|
|
||||||
|
|
||||||
static SRes CMtThread_Prepare(CMtThread *p)
|
|
||||||
{
|
|
||||||
MY_BUF_ALLOC(p->inBuf, p->inBufSize, p->mtCoder->blockSize)
|
|
||||||
MY_BUF_ALLOC(p->outBuf, p->outBufSize, p->mtCoder->destBlockSize)
|
|
||||||
|
|
||||||
p->stopReading = False;
|
|
||||||
p->stopWriting = False;
|
|
||||||
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canRead));
|
|
||||||
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canWrite));
|
|
||||||
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static SRes FullRead(ISeqInStream *stream, Byte *data, size_t *processedSize)
|
static SRes FullRead(ISeqInStream *stream, Byte *data, size_t *processedSize)
|
||||||
{
|
{
|
||||||
@@ -170,158 +148,509 @@ static SRes FullRead(ISeqInStream *stream, Byte *data, size_t *processedSize)
|
|||||||
*processedSize = 0;
|
*processedSize = 0;
|
||||||
while (size != 0)
|
while (size != 0)
|
||||||
{
|
{
|
||||||
size_t curSize = size;
|
size_t cur = size;
|
||||||
SRes res = stream->Read(stream, data, &curSize);
|
SRes res = ISeqInStream_Read(stream, data, &cur);
|
||||||
*processedSize += curSize;
|
*processedSize += cur;
|
||||||
data += curSize;
|
data += cur;
|
||||||
size -= curSize;
|
size -= cur;
|
||||||
RINOK(res);
|
RINOK(res);
|
||||||
if (curSize == 0)
|
if (cur == 0)
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GET_NEXT_THREAD(p) &p->mtCoder->threads[p->index == p->mtCoder->numThreads - 1 ? 0 : p->index + 1]
|
|
||||||
|
|
||||||
static SRes MtThread_Process(CMtThread *p, Bool *stop)
|
/*
|
||||||
|
ThreadFunc2() returns:
|
||||||
|
SZ_OK - in all normal cases (even for stream error or memory allocation error)
|
||||||
|
SZ_ERROR_THREAD - in case of failure in system synch function
|
||||||
|
*/
|
||||||
|
|
||||||
|
static SRes ThreadFunc2(CMtCoderThread *t)
|
||||||
{
|
{
|
||||||
CMtThread *next;
|
CMtCoder *mtc = t->mtCoder;
|
||||||
*stop = True;
|
|
||||||
if (Event_Wait(&p->canRead) != 0)
|
|
||||||
return SZ_ERROR_THREAD;
|
|
||||||
|
|
||||||
next = GET_NEXT_THREAD(p);
|
|
||||||
|
|
||||||
if (p->stopReading)
|
|
||||||
{
|
|
||||||
next->stopReading = True;
|
|
||||||
return Event_Set(&next->canRead) == 0 ? SZ_OK : SZ_ERROR_THREAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
size_t size = p->mtCoder->blockSize;
|
|
||||||
size_t destSize = p->outBufSize;
|
|
||||||
|
|
||||||
RINOK(FullRead(p->mtCoder->inStream, p->inBuf, &size));
|
|
||||||
next->stopReading = *stop = (size != p->mtCoder->blockSize);
|
|
||||||
if (Event_Set(&next->canRead) != 0)
|
|
||||||
return SZ_ERROR_THREAD;
|
|
||||||
|
|
||||||
RINOK(p->mtCoder->mtCallback->Code(p->mtCoder->mtCallback, p->index,
|
|
||||||
p->outBuf, &destSize, p->inBuf, size, *stop));
|
|
||||||
|
|
||||||
MtProgress_Reinit(&p->mtCoder->mtProgress, p->index);
|
|
||||||
|
|
||||||
if (Event_Wait(&p->canWrite) != 0)
|
|
||||||
return SZ_ERROR_THREAD;
|
|
||||||
if (p->stopWriting)
|
|
||||||
return SZ_ERROR_FAIL;
|
|
||||||
if (p->mtCoder->outStream->Write(p->mtCoder->outStream, p->outBuf, destSize) != destSize)
|
|
||||||
return SZ_ERROR_WRITE;
|
|
||||||
return Event_Set(&next->canWrite) == 0 ? SZ_OK : SZ_ERROR_THREAD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE ThreadFunc(void *pp)
|
|
||||||
{
|
|
||||||
CMtThread *p = (CMtThread *)pp;
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Bool stop;
|
unsigned bi;
|
||||||
CMtThread *next = GET_NEXT_THREAD(p);
|
SRes res;
|
||||||
SRes res = MtThread_Process(p, &stop);
|
SRes res2;
|
||||||
if (res != SZ_OK)
|
Bool finished;
|
||||||
|
unsigned bufIndex;
|
||||||
|
size_t size;
|
||||||
|
const Byte *inData;
|
||||||
|
UInt64 readProcessed = 0;
|
||||||
|
|
||||||
|
RINOK_THREAD(Event_Wait(&mtc->readEvent))
|
||||||
|
|
||||||
|
/* after Event_Wait(&mtc->readEvent) we must call Event_Set(&mtc->readEvent) in any case to unlock another threads */
|
||||||
|
|
||||||
|
if (mtc->stopReading)
|
||||||
{
|
{
|
||||||
MtCoder_SetError(p->mtCoder, res);
|
return Event_Set(&mtc->readEvent) == 0 ? SZ_OK : SZ_ERROR_THREAD;
|
||||||
MtProgress_SetError(&p->mtCoder->mtProgress, res);
|
|
||||||
next->stopReading = True;
|
|
||||||
next->stopWriting = True;
|
|
||||||
Event_Set(&next->canRead);
|
|
||||||
Event_Set(&next->canWrite);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
if (stop)
|
|
||||||
|
res = MtProgress_GetError(&mtc->mtProgress);
|
||||||
|
|
||||||
|
size = 0;
|
||||||
|
inData = NULL;
|
||||||
|
finished = True;
|
||||||
|
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
size = mtc->blockSize;
|
||||||
|
if (mtc->inStream)
|
||||||
|
{
|
||||||
|
if (!t->inBuf)
|
||||||
|
{
|
||||||
|
t->inBuf = (Byte *)ISzAlloc_Alloc(mtc->allocBig, mtc->blockSize);
|
||||||
|
if (!t->inBuf)
|
||||||
|
res = SZ_ERROR_MEM;
|
||||||
|
}
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
res = FullRead(mtc->inStream, t->inBuf, &size);
|
||||||
|
readProcessed = mtc->readProcessed + size;
|
||||||
|
mtc->readProcessed = readProcessed;
|
||||||
|
}
|
||||||
|
if (res != SZ_OK)
|
||||||
|
{
|
||||||
|
mtc->readRes = res;
|
||||||
|
/* after reading error - we can stop encoding of previous blocks */
|
||||||
|
MtProgress_SetError(&mtc->mtProgress, res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
finished = (size != mtc->blockSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t rem;
|
||||||
|
readProcessed = mtc->readProcessed;
|
||||||
|
rem = mtc->inDataSize - (size_t)readProcessed;
|
||||||
|
if (size > rem)
|
||||||
|
size = rem;
|
||||||
|
inData = mtc->inData + (size_t)readProcessed;
|
||||||
|
readProcessed += size;
|
||||||
|
mtc->readProcessed = readProcessed;
|
||||||
|
finished = (mtc->inDataSize == (size_t)readProcessed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we must get some block from blocksSemaphore before Event_Set(&mtc->readEvent) */
|
||||||
|
|
||||||
|
res2 = SZ_OK;
|
||||||
|
|
||||||
|
if (Semaphore_Wait(&mtc->blocksSemaphore) != 0)
|
||||||
|
{
|
||||||
|
res2 = SZ_ERROR_THREAD;
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
res = res2;
|
||||||
|
// MtProgress_SetError(&mtc->mtProgress, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bi = mtc->blockIndex;
|
||||||
|
|
||||||
|
if (++mtc->blockIndex >= mtc->numBlocksMax)
|
||||||
|
mtc->blockIndex = 0;
|
||||||
|
|
||||||
|
bufIndex = (unsigned)(int)-1;
|
||||||
|
|
||||||
|
if (res == SZ_OK)
|
||||||
|
res = MtProgress_GetError(&mtc->mtProgress);
|
||||||
|
|
||||||
|
if (res != SZ_OK)
|
||||||
|
finished = True;
|
||||||
|
|
||||||
|
if (!finished)
|
||||||
|
{
|
||||||
|
if (mtc->numStartedThreads < mtc->numStartedThreadsLimit
|
||||||
|
&& mtc->expectedDataSize != readProcessed)
|
||||||
|
{
|
||||||
|
res = MtCoderThread_CreateAndStart(&mtc->threads[mtc->numStartedThreads]);
|
||||||
|
if (res == SZ_OK)
|
||||||
|
mtc->numStartedThreads++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MtProgress_SetError(&mtc->mtProgress, res);
|
||||||
|
finished = True;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (finished)
|
||||||
|
mtc->stopReading = True;
|
||||||
|
|
||||||
|
RINOK_THREAD(Event_Set(&mtc->readEvent))
|
||||||
|
|
||||||
|
if (res2 != SZ_OK)
|
||||||
|
return res2;
|
||||||
|
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
CriticalSection_Enter(&mtc->cs);
|
||||||
|
bufIndex = mtc->freeBlockHead;
|
||||||
|
mtc->freeBlockHead = mtc->freeBlockList[bufIndex];
|
||||||
|
CriticalSection_Leave(&mtc->cs);
|
||||||
|
|
||||||
|
res = mtc->mtCallback->Code(mtc->mtCallbackObject, t->index, bufIndex,
|
||||||
|
mtc->inStream ? t->inBuf : inData, size, finished);
|
||||||
|
|
||||||
|
MtProgress_Reinit(&mtc->mtProgress, t->index);
|
||||||
|
|
||||||
|
if (res != SZ_OK)
|
||||||
|
MtProgress_SetError(&mtc->mtProgress, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
CMtCoderBlock *block = &mtc->blocks[bi];
|
||||||
|
block->res = res;
|
||||||
|
block->bufIndex = bufIndex;
|
||||||
|
block->finished = finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MTCODER__USE_WRITE_THREAD
|
||||||
|
RINOK_THREAD(Event_Set(&mtc->writeEvents[bi]))
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
unsigned wi;
|
||||||
|
{
|
||||||
|
CriticalSection_Enter(&mtc->cs);
|
||||||
|
wi = mtc->writeIndex;
|
||||||
|
if (wi == bi)
|
||||||
|
mtc->writeIndex = (unsigned)(int)-1;
|
||||||
|
else
|
||||||
|
mtc->ReadyBlocks[bi] = True;
|
||||||
|
CriticalSection_Leave(&mtc->cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wi != bi)
|
||||||
|
{
|
||||||
|
if (res != SZ_OK || finished)
|
||||||
|
return 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mtc->writeRes != SZ_OK)
|
||||||
|
res = mtc->writeRes;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (res == SZ_OK && bufIndex != (unsigned)(int)-1)
|
||||||
|
{
|
||||||
|
res = mtc->mtCallback->Write(mtc->mtCallbackObject, bufIndex);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
{
|
||||||
|
mtc->writeRes = res;
|
||||||
|
MtProgress_SetError(&mtc->mtProgress, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++wi >= mtc->numBlocksMax)
|
||||||
|
wi = 0;
|
||||||
|
{
|
||||||
|
Bool isReady;
|
||||||
|
|
||||||
|
CriticalSection_Enter(&mtc->cs);
|
||||||
|
|
||||||
|
if (bufIndex != (unsigned)(int)-1)
|
||||||
|
{
|
||||||
|
mtc->freeBlockList[bufIndex] = mtc->freeBlockHead;
|
||||||
|
mtc->freeBlockHead = bufIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
isReady = mtc->ReadyBlocks[wi];
|
||||||
|
|
||||||
|
if (isReady)
|
||||||
|
mtc->ReadyBlocks[wi] = False;
|
||||||
|
else
|
||||||
|
mtc->writeIndex = wi;
|
||||||
|
|
||||||
|
CriticalSection_Leave(&mtc->cs);
|
||||||
|
|
||||||
|
RINOK_THREAD(Semaphore_Release1(&mtc->blocksSemaphore))
|
||||||
|
|
||||||
|
if (!isReady)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
CMtCoderBlock *block = &mtc->blocks[wi];
|
||||||
|
if (res == SZ_OK && block->res != SZ_OK)
|
||||||
|
res = block->res;
|
||||||
|
bufIndex = block->bufIndex;
|
||||||
|
finished = block->finished;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (finished || res != SZ_OK)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MtCoder_Construct(CMtCoder* p)
|
|
||||||
|
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE ThreadFunc(void *pp)
|
||||||
|
{
|
||||||
|
CMtCoderThread *t = (CMtCoderThread *)pp;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (Event_Wait(&t->startEvent) != 0)
|
||||||
|
return SZ_ERROR_THREAD;
|
||||||
|
if (t->stop)
|
||||||
|
return 0;
|
||||||
|
{
|
||||||
|
SRes res = ThreadFunc2(t);
|
||||||
|
CMtCoder *mtc = t->mtCoder;
|
||||||
|
if (res != SZ_OK)
|
||||||
|
{
|
||||||
|
MtProgress_SetError(&mtc->mtProgress, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef MTCODER__USE_WRITE_THREAD
|
||||||
|
{
|
||||||
|
unsigned numFinished = (unsigned)InterlockedIncrement(&mtc->numFinishedThreads);
|
||||||
|
if (numFinished == mtc->numStartedThreads)
|
||||||
|
if (Event_Set(&mtc->finishedEvent) != 0)
|
||||||
|
return SZ_ERROR_THREAD;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void MtCoder_Construct(CMtCoder *p)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
p->alloc = 0;
|
|
||||||
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
|
p->blockSize = 0;
|
||||||
|
p->numThreadsMax = 0;
|
||||||
|
p->expectedDataSize = (UInt64)(Int64)-1;
|
||||||
|
|
||||||
|
p->inStream = NULL;
|
||||||
|
p->inData = NULL;
|
||||||
|
p->inDataSize = 0;
|
||||||
|
|
||||||
|
p->progress = NULL;
|
||||||
|
p->allocBig = NULL;
|
||||||
|
|
||||||
|
p->mtCallback = NULL;
|
||||||
|
p->mtCallbackObject = NULL;
|
||||||
|
|
||||||
|
p->allocatedBufsSize = 0;
|
||||||
|
|
||||||
|
Event_Construct(&p->readEvent);
|
||||||
|
Semaphore_Construct(&p->blocksSemaphore);
|
||||||
|
|
||||||
|
for (i = 0; i < MTCODER__THREADS_MAX; i++)
|
||||||
{
|
{
|
||||||
CMtThread *t = &p->threads[i];
|
CMtCoderThread *t = &p->threads[i];
|
||||||
|
t->mtCoder = p;
|
||||||
t->index = i;
|
t->index = i;
|
||||||
CMtThread_Construct(t, p);
|
t->inBuf = NULL;
|
||||||
|
t->stop = False;
|
||||||
|
Event_Construct(&t->startEvent);
|
||||||
|
Thread_Construct(&t->thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MTCODER__USE_WRITE_THREAD
|
||||||
|
for (i = 0; i < MTCODER__BLOCKS_MAX; i++)
|
||||||
|
Event_Construct(&p->writeEvents[i]);
|
||||||
|
#else
|
||||||
|
Event_Construct(&p->finishedEvent);
|
||||||
|
#endif
|
||||||
|
|
||||||
CriticalSection_Init(&p->cs);
|
CriticalSection_Init(&p->cs);
|
||||||
CriticalSection_Init(&p->mtProgress.cs);
|
CriticalSection_Init(&p->mtProgress.cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MtCoder_Destruct(CMtCoder* p)
|
|
||||||
|
|
||||||
|
|
||||||
|
static void MtCoder_Free(CMtCoder *p)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
|
|
||||||
CMtThread_Destruct(&p->threads[i]);
|
/*
|
||||||
|
p->stopReading = True;
|
||||||
|
if (Event_IsCreated(&p->readEvent))
|
||||||
|
Event_Set(&p->readEvent);
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (i = 0; i < MTCODER__THREADS_MAX; i++)
|
||||||
|
MtCoderThread_Destruct(&p->threads[i]);
|
||||||
|
|
||||||
|
Event_Close(&p->readEvent);
|
||||||
|
Semaphore_Close(&p->blocksSemaphore);
|
||||||
|
|
||||||
|
#ifdef MTCODER__USE_WRITE_THREAD
|
||||||
|
for (i = 0; i < MTCODER__BLOCKS_MAX; i++)
|
||||||
|
Event_Close(&p->writeEvents[i]);
|
||||||
|
#else
|
||||||
|
Event_Close(&p->finishedEvent);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MtCoder_Destruct(CMtCoder *p)
|
||||||
|
{
|
||||||
|
MtCoder_Free(p);
|
||||||
|
|
||||||
CriticalSection_Delete(&p->cs);
|
CriticalSection_Delete(&p->cs);
|
||||||
CriticalSection_Delete(&p->mtProgress.cs);
|
CriticalSection_Delete(&p->mtProgress.cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SRes MtCoder_Code(CMtCoder *p)
|
SRes MtCoder_Code(CMtCoder *p)
|
||||||
{
|
{
|
||||||
unsigned i, numThreads = p->numThreads;
|
unsigned numThreads = p->numThreadsMax;
|
||||||
|
unsigned numBlocksMax;
|
||||||
|
unsigned i;
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
p->res = SZ_OK;
|
|
||||||
|
if (numThreads > MTCODER__THREADS_MAX)
|
||||||
|
numThreads = MTCODER__THREADS_MAX;
|
||||||
|
numBlocksMax = MTCODER__GET_NUM_BLOCKS_FROM_THREADS(numThreads);
|
||||||
|
|
||||||
|
if (p->blockSize < ((UInt32)1 << 26)) numBlocksMax++;
|
||||||
|
if (p->blockSize < ((UInt32)1 << 24)) numBlocksMax++;
|
||||||
|
if (p->blockSize < ((UInt32)1 << 22)) numBlocksMax++;
|
||||||
|
|
||||||
|
if (numBlocksMax > MTCODER__BLOCKS_MAX)
|
||||||
|
numBlocksMax = MTCODER__BLOCKS_MAX;
|
||||||
|
|
||||||
|
if (p->blockSize != p->allocatedBufsSize)
|
||||||
|
{
|
||||||
|
for (i = 0; i < MTCODER__THREADS_MAX; i++)
|
||||||
|
{
|
||||||
|
CMtCoderThread *t = &p->threads[i];
|
||||||
|
if (t->inBuf)
|
||||||
|
{
|
||||||
|
ISzAlloc_Free(p->allocBig, t->inBuf);
|
||||||
|
t->inBuf = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->allocatedBufsSize = p->blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->readRes = SZ_OK;
|
||||||
|
|
||||||
MtProgress_Init(&p->mtProgress, p->progress);
|
MtProgress_Init(&p->mtProgress, p->progress);
|
||||||
|
|
||||||
for (i = 0; i < numThreads; i++)
|
#ifdef MTCODER__USE_WRITE_THREAD
|
||||||
|
for (i = 0; i < numBlocksMax; i++)
|
||||||
|
{
|
||||||
|
RINOK_THREAD(ArEvent_OptCreate_And_Reset(&p->writeEvents[i]));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
RINOK_THREAD(ArEvent_OptCreate_And_Reset(&p->finishedEvent));
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
RINOK(CMtThread_Prepare(&p->threads[i]));
|
RINOK_THREAD(ArEvent_OptCreate_And_Reset(&p->readEvent));
|
||||||
|
|
||||||
|
if (Semaphore_IsCreated(&p->blocksSemaphore))
|
||||||
|
{
|
||||||
|
RINOK_THREAD(Semaphore_Close(&p->blocksSemaphore));
|
||||||
|
}
|
||||||
|
RINOK_THREAD(Semaphore_Create(&p->blocksSemaphore, numBlocksMax, numBlocksMax));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < numThreads; i++)
|
for (i = 0; i < MTCODER__BLOCKS_MAX - 1; i++)
|
||||||
|
p->freeBlockList[i] = i + 1;
|
||||||
|
p->freeBlockList[MTCODER__BLOCKS_MAX - 1] = (unsigned)(int)-1;
|
||||||
|
p->freeBlockHead = 0;
|
||||||
|
|
||||||
|
p->readProcessed = 0;
|
||||||
|
p->blockIndex = 0;
|
||||||
|
p->numBlocksMax = numBlocksMax;
|
||||||
|
p->stopReading = False;
|
||||||
|
|
||||||
|
#ifndef MTCODER__USE_WRITE_THREAD
|
||||||
|
p->writeIndex = 0;
|
||||||
|
p->writeRes = SZ_OK;
|
||||||
|
for (i = 0; i < MTCODER__BLOCKS_MAX; i++)
|
||||||
|
p->ReadyBlocks[i] = False;
|
||||||
|
p->numFinishedThreads = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
p->numStartedThreadsLimit = numThreads;
|
||||||
|
p->numStartedThreads = 0;
|
||||||
|
|
||||||
|
// for (i = 0; i < numThreads; i++)
|
||||||
{
|
{
|
||||||
CMtThread *t = &p->threads[i];
|
CMtCoderThread *nextThread = &p->threads[p->numStartedThreads++];
|
||||||
CLoopThread *lt = &t->thread;
|
RINOK(MtCoderThread_CreateAndStart(nextThread));
|
||||||
|
}
|
||||||
|
|
||||||
if (!Thread_WasCreated(<->thread))
|
RINOK_THREAD(Event_Set(&p->readEvent))
|
||||||
|
|
||||||
|
#ifdef MTCODER__USE_WRITE_THREAD
|
||||||
|
{
|
||||||
|
unsigned bi = 0;
|
||||||
|
|
||||||
|
for (;; bi++)
|
||||||
{
|
{
|
||||||
lt->func = ThreadFunc;
|
if (bi >= numBlocksMax)
|
||||||
lt->param = t;
|
bi = 0;
|
||||||
|
|
||||||
|
RINOK_THREAD(Event_Wait(&p->writeEvents[bi]))
|
||||||
|
|
||||||
if (LoopThread_Create(lt) != SZ_OK)
|
|
||||||
{
|
{
|
||||||
res = SZ_ERROR_THREAD;
|
const CMtCoderBlock *block = &p->blocks[bi];
|
||||||
break;
|
unsigned bufIndex = block->bufIndex;
|
||||||
|
Bool finished = block->finished;
|
||||||
|
if (res == SZ_OK && block->res != SZ_OK)
|
||||||
|
res = block->res;
|
||||||
|
|
||||||
|
if (bufIndex != (unsigned)(int)-1)
|
||||||
|
{
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
res = p->mtCallback->Write(p->mtCallbackObject, bufIndex);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
MtProgress_SetError(&p->mtProgress, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
CriticalSection_Enter(&p->cs);
|
||||||
|
{
|
||||||
|
p->freeBlockList[bufIndex] = p->freeBlockHead;
|
||||||
|
p->freeBlockHead = bufIndex;
|
||||||
|
}
|
||||||
|
CriticalSection_Leave(&p->cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
RINOK_THREAD(Semaphore_Release1(&p->blocksSemaphore))
|
||||||
|
|
||||||
|
if (finished)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
WRes wres = Event_Wait(&p->finishedEvent);
|
||||||
|
res = MY_SRes_HRESULT_FROM_WRes(wres);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
res = p->readRes;
|
||||||
unsigned j;
|
|
||||||
for (i = 0; i < numThreads; i++)
|
|
||||||
{
|
|
||||||
CMtThread *t = &p->threads[i];
|
|
||||||
if (LoopThread_StartSubThread(&t->thread) != SZ_OK)
|
|
||||||
{
|
|
||||||
res = SZ_ERROR_THREAD;
|
|
||||||
p->threads[0].stopReading = True;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Event_Set(&p->threads[0].canWrite);
|
if (res == SZ_OK)
|
||||||
Event_Set(&p->threads[0].canRead);
|
res = p->mtProgress.res;
|
||||||
|
|
||||||
for (j = 0; j < i; j++)
|
#ifndef MTCODER__USE_WRITE_THREAD
|
||||||
LoopThread_WaitSubThread(&p->threads[j].thread);
|
if (res == SZ_OK)
|
||||||
}
|
res = p->writeRes;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < numThreads; i++)
|
if (res != SZ_OK)
|
||||||
CMtThread_CloseEvents(&p->threads[i]);
|
MtCoder_Free(p);
|
||||||
return (res == SZ_OK) ? p->res : res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
153
C/MtCoder.h
153
C/MtCoder.h
@@ -1,5 +1,5 @@
|
|||||||
/* MtCoder.h -- Multi-thread Coder
|
/* MtCoder.h -- Multi-thread Coder
|
||||||
2009-11-19 : Igor Pavlov : Public domain */
|
2017-06-18 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __MT_CODER_H
|
#ifndef __MT_CODER_H
|
||||||
#define __MT_CODER_H
|
#define __MT_CODER_H
|
||||||
@@ -8,91 +8,144 @@
|
|||||||
|
|
||||||
EXTERN_C_BEGIN
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
typedef struct
|
/*
|
||||||
{
|
if ( defined MTCODER__USE_WRITE_THREAD) : main thread writes all data blocks to output stream
|
||||||
CThread thread;
|
if (not defined MTCODER__USE_WRITE_THREAD) : any coder thread can write data blocks to output stream
|
||||||
CAutoResetEvent startEvent;
|
*/
|
||||||
CAutoResetEvent finishedEvent;
|
/* #define MTCODER__USE_WRITE_THREAD */
|
||||||
int stop;
|
|
||||||
|
|
||||||
THREAD_FUNC_TYPE func;
|
|
||||||
LPVOID param;
|
|
||||||
THREAD_FUNC_RET_TYPE res;
|
|
||||||
} CLoopThread;
|
|
||||||
|
|
||||||
void LoopThread_Construct(CLoopThread *p);
|
|
||||||
void LoopThread_Close(CLoopThread *p);
|
|
||||||
WRes LoopThread_Create(CLoopThread *p);
|
|
||||||
WRes LoopThread_StopAndWait(CLoopThread *p);
|
|
||||||
WRes LoopThread_StartSubThread(CLoopThread *p);
|
|
||||||
WRes LoopThread_WaitSubThread(CLoopThread *p);
|
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
#define NUM_MT_CODER_THREADS_MAX 32
|
#define MTCODER__GET_NUM_BLOCKS_FROM_THREADS(numThreads) ((numThreads) + (numThreads) / 8 + 1)
|
||||||
|
#define MTCODER__THREADS_MAX 64
|
||||||
|
#define MTCODER__BLOCKS_MAX (MTCODER__GET_NUM_BLOCKS_FROM_THREADS(MTCODER__THREADS_MAX) + 3)
|
||||||
#else
|
#else
|
||||||
#define NUM_MT_CODER_THREADS_MAX 1
|
#define MTCODER__THREADS_MAX 1
|
||||||
|
#define MTCODER__BLOCKS_MAX 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt64 inSize;
|
||||||
|
UInt64 outSize;
|
||||||
|
} CMtProgressSizes;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UInt64 totalInSize;
|
|
||||||
UInt64 totalOutSize;
|
|
||||||
ICompressProgress *progress;
|
ICompressProgress *progress;
|
||||||
SRes res;
|
SRes res;
|
||||||
|
UInt64 totalInSize;
|
||||||
|
UInt64 totalOutSize;
|
||||||
CCriticalSection cs;
|
CCriticalSection cs;
|
||||||
UInt64 inSizes[NUM_MT_CODER_THREADS_MAX];
|
CMtProgressSizes sizes[MTCODER__THREADS_MAX];
|
||||||
UInt64 outSizes[NUM_MT_CODER_THREADS_MAX];
|
|
||||||
} CMtProgress;
|
} CMtProgress;
|
||||||
|
|
||||||
SRes MtProgress_Set(CMtProgress *p, unsigned index, UInt64 inSize, UInt64 outSize);
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ICompressProgress vt;
|
||||||
|
CMtProgress *mtProgress;
|
||||||
|
unsigned index;
|
||||||
|
} CMtProgressThunk;
|
||||||
|
|
||||||
|
void MtProgressThunk_CreateVTable(CMtProgressThunk *p);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct _CMtCoder;
|
struct _CMtCoder;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
struct _CMtCoder *mtCoder;
|
struct _CMtCoder *mtCoder;
|
||||||
Byte *outBuf;
|
|
||||||
size_t outBufSize;
|
|
||||||
Byte *inBuf;
|
|
||||||
size_t inBufSize;
|
|
||||||
unsigned index;
|
unsigned index;
|
||||||
CLoopThread thread;
|
int stop;
|
||||||
|
Byte *inBuf;
|
||||||
|
|
||||||
|
CAutoResetEvent startEvent;
|
||||||
|
CThread thread;
|
||||||
|
} CMtCoderThread;
|
||||||
|
|
||||||
Bool stopReading;
|
|
||||||
Bool stopWriting;
|
|
||||||
CAutoResetEvent canRead;
|
|
||||||
CAutoResetEvent canWrite;
|
|
||||||
} CMtThread;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
SRes (*Code)(void *p, unsigned index, Byte *dest, size_t *destSize,
|
SRes (*Code)(void *p, unsigned coderIndex, unsigned outBufIndex,
|
||||||
const Byte *src, size_t srcSize, int finished);
|
const Byte *src, size_t srcSize, int finished);
|
||||||
} IMtCoderCallback;
|
SRes (*Write)(void *p, unsigned outBufIndex);
|
||||||
|
} IMtCoderCallback2;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
SRes res;
|
||||||
|
unsigned bufIndex;
|
||||||
|
Bool finished;
|
||||||
|
} CMtCoderBlock;
|
||||||
|
|
||||||
|
|
||||||
typedef struct _CMtCoder
|
typedef struct _CMtCoder
|
||||||
{
|
{
|
||||||
size_t blockSize;
|
/* input variables */
|
||||||
size_t destBlockSize;
|
|
||||||
unsigned numThreads;
|
|
||||||
|
|
||||||
ISeqInStream *inStream;
|
size_t blockSize; /* size of input block */
|
||||||
ISeqOutStream *outStream;
|
unsigned numThreadsMax;
|
||||||
ICompressProgress *progress;
|
UInt64 expectedDataSize;
|
||||||
ISzAlloc *alloc;
|
|
||||||
|
ISeqInStream *inStream;
|
||||||
|
const Byte *inData;
|
||||||
|
size_t inDataSize;
|
||||||
|
|
||||||
|
ICompressProgress *progress;
|
||||||
|
ISzAllocPtr allocBig;
|
||||||
|
|
||||||
|
IMtCoderCallback2 *mtCallback;
|
||||||
|
void *mtCallbackObject;
|
||||||
|
|
||||||
|
|
||||||
|
/* internal variables */
|
||||||
|
|
||||||
|
size_t allocatedBufsSize;
|
||||||
|
|
||||||
|
CAutoResetEvent readEvent;
|
||||||
|
CSemaphore blocksSemaphore;
|
||||||
|
|
||||||
|
Bool stopReading;
|
||||||
|
SRes readRes;
|
||||||
|
|
||||||
|
#ifdef MTCODER__USE_WRITE_THREAD
|
||||||
|
CAutoResetEvent writeEvents[MTCODER__BLOCKS_MAX];
|
||||||
|
#else
|
||||||
|
CAutoResetEvent finishedEvent;
|
||||||
|
SRes writeRes;
|
||||||
|
unsigned writeIndex;
|
||||||
|
Byte ReadyBlocks[MTCODER__BLOCKS_MAX];
|
||||||
|
LONG numFinishedThreads;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned numStartedThreadsLimit;
|
||||||
|
unsigned numStartedThreads;
|
||||||
|
|
||||||
|
unsigned numBlocksMax;
|
||||||
|
unsigned blockIndex;
|
||||||
|
UInt64 readProcessed;
|
||||||
|
|
||||||
IMtCoderCallback *mtCallback;
|
|
||||||
CCriticalSection cs;
|
CCriticalSection cs;
|
||||||
SRes res;
|
|
||||||
|
unsigned freeBlockHead;
|
||||||
|
unsigned freeBlockList[MTCODER__BLOCKS_MAX];
|
||||||
|
|
||||||
CMtProgress mtProgress;
|
CMtProgress mtProgress;
|
||||||
CMtThread threads[NUM_MT_CODER_THREADS_MAX];
|
CMtCoderBlock blocks[MTCODER__BLOCKS_MAX];
|
||||||
|
CMtCoderThread threads[MTCODER__THREADS_MAX];
|
||||||
} CMtCoder;
|
} CMtCoder;
|
||||||
|
|
||||||
void MtCoder_Construct(CMtCoder* p);
|
|
||||||
void MtCoder_Destruct(CMtCoder* p);
|
void MtCoder_Construct(CMtCoder *p);
|
||||||
|
void MtCoder_Destruct(CMtCoder *p);
|
||||||
SRes MtCoder_Code(CMtCoder *p);
|
SRes MtCoder_Code(CMtCoder *p);
|
||||||
|
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
6
C/Ppmd.h
6
C/Ppmd.h
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd.h -- PPMD codec common code
|
/* Ppmd.h -- PPMD codec common code
|
||||||
2013-01-18 : Igor Pavlov : Public domain
|
2017-04-03 : Igor Pavlov : Public domain
|
||||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||||
|
|
||||||
#ifndef __PPMD_H
|
#ifndef __PPMD_H
|
||||||
@@ -77,8 +77,8 @@ typedef
|
|||||||
CPpmd_Byte_Ref;
|
CPpmd_Byte_Ref;
|
||||||
|
|
||||||
#define PPMD_SetAllBitsIn256Bytes(p) \
|
#define PPMD_SetAllBitsIn256Bytes(p) \
|
||||||
{ unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \
|
{ size_t z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \
|
||||||
p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }}
|
p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }}
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
|
|||||||
32
C/Ppmd7.c
32
C/Ppmd7.c
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd7.c -- PPMdH codec
|
/* Ppmd7.c -- PPMdH codec
|
||||||
2015-09-28 : Igor Pavlov : Public domain
|
2017-04-03 : Igor Pavlov : Public domain
|
||||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
@@ -15,7 +15,7 @@ static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x
|
|||||||
#define UNIT_SIZE 12
|
#define UNIT_SIZE 12
|
||||||
|
|
||||||
#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
|
#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
|
||||||
#define U2I(nu) (p->Units2Indx[(nu) - 1])
|
#define U2I(nu) (p->Units2Indx[(size_t)(nu) - 1])
|
||||||
#define I2U(indx) (p->Indx2Units[indx])
|
#define I2U(indx) (p->Indx2Units[indx])
|
||||||
|
|
||||||
#ifdef PPMD_32BIT
|
#ifdef PPMD_32BIT
|
||||||
@@ -88,29 +88,31 @@ void Ppmd7_Construct(CPpmd7 *p)
|
|||||||
memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
|
memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc)
|
void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->Base);
|
ISzAlloc_Free(alloc, p->Base);
|
||||||
p->Size = 0;
|
p->Size = 0;
|
||||||
p->Base = 0;
|
p->Base = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
|
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
if (p->Base == 0 || p->Size != size)
|
if (!p->Base || p->Size != size)
|
||||||
{
|
{
|
||||||
|
size_t size2;
|
||||||
Ppmd7_Free(p, alloc);
|
Ppmd7_Free(p, alloc);
|
||||||
|
size2 = 0
|
||||||
|
#ifndef PPMD_32BIT
|
||||||
|
+ UNIT_SIZE
|
||||||
|
#endif
|
||||||
|
;
|
||||||
p->AlignOffset =
|
p->AlignOffset =
|
||||||
#ifdef PPMD_32BIT
|
#ifdef PPMD_32BIT
|
||||||
(4 - size) & 3;
|
(4 - size) & 3;
|
||||||
#else
|
#else
|
||||||
4 - (size & 3);
|
4 - (size & 3);
|
||||||
#endif
|
#endif
|
||||||
if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size
|
if ((p->Base = (Byte *)ISzAlloc_Alloc(alloc, p->AlignOffset + size + size2)) == 0)
|
||||||
#ifndef PPMD_32BIT
|
|
||||||
+ UNIT_SIZE
|
|
||||||
#endif
|
|
||||||
)) == 0)
|
|
||||||
return False;
|
return False;
|
||||||
p->Size = size;
|
p->Size = size;
|
||||||
}
|
}
|
||||||
@@ -513,7 +515,7 @@ static void UpdateModel(CPpmd7 *p)
|
|||||||
/* Expand for one UNIT */
|
/* Expand for one UNIT */
|
||||||
unsigned oldNU = ns1 >> 1;
|
unsigned oldNU = ns1 >> 1;
|
||||||
unsigned i = U2I(oldNU);
|
unsigned i = U2I(oldNU);
|
||||||
if (i != U2I(oldNU + 1))
|
if (i != U2I((size_t)oldNU + 1))
|
||||||
{
|
{
|
||||||
void *ptr = AllocUnits(p, i + 1);
|
void *ptr = AllocUnits(p, i + 1);
|
||||||
void *oldPtr;
|
void *oldPtr;
|
||||||
@@ -639,10 +641,10 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
|
|||||||
unsigned nonMasked = p->MinContext->NumStats - numMasked;
|
unsigned nonMasked = p->MinContext->NumStats - numMasked;
|
||||||
if (p->MinContext->NumStats != 256)
|
if (p->MinContext->NumStats != 256)
|
||||||
{
|
{
|
||||||
see = p->See[p->NS2Indx[nonMasked - 1]] +
|
see = p->See[(unsigned)p->NS2Indx[(size_t)nonMasked - 1]] +
|
||||||
(nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
|
(nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
|
||||||
2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
|
2 * (unsigned)(p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
|
||||||
4 * (numMasked > nonMasked) +
|
4 * (unsigned)(numMasked > nonMasked) +
|
||||||
p->HiBitsFlag;
|
p->HiBitsFlag;
|
||||||
{
|
{
|
||||||
unsigned r = (see->Summ >> see->Shift);
|
unsigned r = (see->Summ >> see->Shift);
|
||||||
|
|||||||
28
C/Ppmd7.h
28
C/Ppmd7.h
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd7.h -- PPMdH compression codec
|
/* Ppmd7.h -- PPMdH compression codec
|
||||||
2010-03-12 : Igor Pavlov : Public domain
|
2017-04-03 : Igor Pavlov : Public domain
|
||||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||||
|
|
||||||
/* This code supports virtual RangeDecoder and includes the implementation
|
/* This code supports virtual RangeDecoder and includes the implementation
|
||||||
@@ -60,8 +60,8 @@ typedef struct
|
|||||||
} CPpmd7;
|
} CPpmd7;
|
||||||
|
|
||||||
void Ppmd7_Construct(CPpmd7 *p);
|
void Ppmd7_Construct(CPpmd7 *p);
|
||||||
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
|
Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc);
|
||||||
void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc);
|
void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc);
|
||||||
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
|
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
|
||||||
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
|
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
|
||||||
|
|
||||||
@@ -86,10 +86,10 @@ void Ppmd7_Update2(CPpmd7 *p);
|
|||||||
void Ppmd7_UpdateBin(CPpmd7 *p);
|
void Ppmd7_UpdateBin(CPpmd7 *p);
|
||||||
|
|
||||||
#define Ppmd7_GetBinSumm(p) \
|
#define Ppmd7_GetBinSumm(p) \
|
||||||
&p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
|
&p->BinSumm[(size_t)(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
|
||||||
p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
|
p->NS2BSIndx[(size_t)Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
|
||||||
(p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
|
(p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
|
||||||
2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \
|
2 * p->HB2Flag[(unsigned)Ppmd7Context_OneState(p->MinContext)->Symbol] + \
|
||||||
((p->RunLength >> 26) & 0x20)]
|
((p->RunLength >> 26) & 0x20)]
|
||||||
|
|
||||||
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
|
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
|
||||||
@@ -97,16 +97,18 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
|
|||||||
|
|
||||||
/* ---------- Decode ---------- */
|
/* ---------- Decode ---------- */
|
||||||
|
|
||||||
typedef struct
|
typedef struct IPpmd7_RangeDec IPpmd7_RangeDec;
|
||||||
|
|
||||||
|
struct IPpmd7_RangeDec
|
||||||
{
|
{
|
||||||
UInt32 (*GetThreshold)(void *p, UInt32 total);
|
UInt32 (*GetThreshold)(const IPpmd7_RangeDec *p, UInt32 total);
|
||||||
void (*Decode)(void *p, UInt32 start, UInt32 size);
|
void (*Decode)(const IPpmd7_RangeDec *p, UInt32 start, UInt32 size);
|
||||||
UInt32 (*DecodeBit)(void *p, UInt32 size0);
|
UInt32 (*DecodeBit)(const IPpmd7_RangeDec *p, UInt32 size0);
|
||||||
} IPpmd7_RangeDec;
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IPpmd7_RangeDec p;
|
IPpmd7_RangeDec vt;
|
||||||
UInt32 Range;
|
UInt32 Range;
|
||||||
UInt32 Code;
|
UInt32 Code;
|
||||||
IByteIn *Stream;
|
IByteIn *Stream;
|
||||||
@@ -116,7 +118,7 @@ void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p);
|
|||||||
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
|
Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
|
||||||
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
|
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
|
||||||
|
|
||||||
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc);
|
int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc);
|
||||||
|
|
||||||
|
|
||||||
/* ---------- Encode ---------- */
|
/* ---------- Encode ---------- */
|
||||||
|
|||||||
34
C/Ppmd7Dec.c
34
C/Ppmd7Dec.c
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd7Dec.c -- PPMdH Decoder
|
/* Ppmd7Dec.c -- PPMdH Decoder
|
||||||
2010-03-12 : Igor Pavlov : Public domain
|
2017-04-03 : Igor Pavlov : Public domain
|
||||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
@@ -13,44 +13,46 @@ Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
|
|||||||
unsigned i;
|
unsigned i;
|
||||||
p->Code = 0;
|
p->Code = 0;
|
||||||
p->Range = 0xFFFFFFFF;
|
p->Range = 0xFFFFFFFF;
|
||||||
if (p->Stream->Read((void *)p->Stream) != 0)
|
if (IByteIn_Read(p->Stream) != 0)
|
||||||
return False;
|
return False;
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
|
p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
|
||||||
return (p->Code < 0xFFFFFFFF);
|
return (p->Code < 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
static UInt32 Range_GetThreshold(void *pp, UInt32 total)
|
#define GET_Ppmd7z_RangeDec CPpmd7z_RangeDec *p = CONTAINER_FROM_VTBL(pp, CPpmd7z_RangeDec, vt);
|
||||||
|
|
||||||
|
static UInt32 Range_GetThreshold(const IPpmd7_RangeDec *pp, UInt32 total)
|
||||||
{
|
{
|
||||||
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
|
GET_Ppmd7z_RangeDec
|
||||||
return (p->Code) / (p->Range /= total);
|
return p->Code / (p->Range /= total);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Range_Normalize(CPpmd7z_RangeDec *p)
|
static void Range_Normalize(CPpmd7z_RangeDec *p)
|
||||||
{
|
{
|
||||||
if (p->Range < kTopValue)
|
if (p->Range < kTopValue)
|
||||||
{
|
{
|
||||||
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
|
p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
|
||||||
p->Range <<= 8;
|
p->Range <<= 8;
|
||||||
if (p->Range < kTopValue)
|
if (p->Range < kTopValue)
|
||||||
{
|
{
|
||||||
p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
|
p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
|
||||||
p->Range <<= 8;
|
p->Range <<= 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Range_Decode(void *pp, UInt32 start, UInt32 size)
|
static void Range_Decode(const IPpmd7_RangeDec *pp, UInt32 start, UInt32 size)
|
||||||
{
|
{
|
||||||
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
|
GET_Ppmd7z_RangeDec
|
||||||
p->Code -= start * p->Range;
|
p->Code -= start * p->Range;
|
||||||
p->Range *= size;
|
p->Range *= size;
|
||||||
Range_Normalize(p);
|
Range_Normalize(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
|
static UInt32 Range_DecodeBit(const IPpmd7_RangeDec *pp, UInt32 size0)
|
||||||
{
|
{
|
||||||
CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
|
GET_Ppmd7z_RangeDec
|
||||||
UInt32 newBound = (p->Range >> 14) * size0;
|
UInt32 newBound = (p->Range >> 14) * size0;
|
||||||
UInt32 symbol;
|
UInt32 symbol;
|
||||||
if (p->Code < newBound)
|
if (p->Code < newBound)
|
||||||
@@ -70,15 +72,15 @@ static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
|
|||||||
|
|
||||||
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
|
void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
|
||||||
{
|
{
|
||||||
p->p.GetThreshold = Range_GetThreshold;
|
p->vt.GetThreshold = Range_GetThreshold;
|
||||||
p->p.Decode = Range_Decode;
|
p->vt.Decode = Range_Decode;
|
||||||
p->p.DecodeBit = Range_DecodeBit;
|
p->vt.DecodeBit = Range_DecodeBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define MASK(sym) ((signed char *)charMask)[sym]
|
#define MASK(sym) ((signed char *)charMask)[sym]
|
||||||
|
|
||||||
int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
|
int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc)
|
||||||
{
|
{
|
||||||
size_t charMask[256 / sizeof(size_t)];
|
size_t charMask[256 / sizeof(size_t)];
|
||||||
if (p->MinContext->NumStats != 1)
|
if (p->MinContext->NumStats != 1)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd7Enc.c -- PPMdH Encoder
|
/* Ppmd7Enc.c -- PPMdH Encoder
|
||||||
2015-09-28 : Igor Pavlov : Public domain
|
2017-04-03 : Igor Pavlov : Public domain
|
||||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
@@ -23,7 +23,7 @@ static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
|
|||||||
Byte temp = p->Cache;
|
Byte temp = p->Cache;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
|
IByteOut_Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
|
||||||
temp = 0xFF;
|
temp = 0xFF;
|
||||||
}
|
}
|
||||||
while (--p->CacheSize != 0);
|
while (--p->CacheSize != 0);
|
||||||
|
|||||||
54
C/Ppmd8.c
54
C/Ppmd8.c
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd8.c -- PPMdI codec
|
/* Ppmd8.c -- PPMdI codec
|
||||||
2015-09-28 : Igor Pavlov : Public domain
|
2017-04-03 : Igor Pavlov : Public domain
|
||||||
This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */
|
This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
@@ -15,7 +15,7 @@ static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x
|
|||||||
#define UNIT_SIZE 12
|
#define UNIT_SIZE 12
|
||||||
|
|
||||||
#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
|
#define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
|
||||||
#define U2I(nu) (p->Units2Indx[(nu) - 1])
|
#define U2I(nu) (p->Units2Indx[(size_t)(nu) - 1])
|
||||||
#define I2U(indx) (p->Indx2Units[indx])
|
#define I2U(indx) (p->Indx2Units[indx])
|
||||||
|
|
||||||
#ifdef PPMD_32BIT
|
#ifdef PPMD_32BIT
|
||||||
@@ -86,16 +86,16 @@ void Ppmd8_Construct(CPpmd8 *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ppmd8_Free(CPpmd8 *p, ISzAlloc *alloc)
|
void Ppmd8_Free(CPpmd8 *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->Base);
|
ISzAlloc_Free(alloc, p->Base);
|
||||||
p->Size = 0;
|
p->Size = 0;
|
||||||
p->Base = 0;
|
p->Base = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc)
|
Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
if (p->Base == 0 || p->Size != size)
|
if (!p->Base || p->Size != size)
|
||||||
{
|
{
|
||||||
Ppmd8_Free(p, alloc);
|
Ppmd8_Free(p, alloc);
|
||||||
p->AlignOffset =
|
p->AlignOffset =
|
||||||
@@ -104,7 +104,7 @@ Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc)
|
|||||||
#else
|
#else
|
||||||
4 - (size & 3);
|
4 - (size & 3);
|
||||||
#endif
|
#endif
|
||||||
if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size)) == 0)
|
if ((p->Base = (Byte *)ISzAlloc_Alloc(alloc, p->AlignOffset + size)) == 0)
|
||||||
return False;
|
return False;
|
||||||
p->Size = size;
|
p->Size = size;
|
||||||
}
|
}
|
||||||
@@ -240,8 +240,8 @@ static void *AllocUnits(CPpmd8 *p, unsigned indx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define MyMem12Cpy(dest, src, num) \
|
#define MyMem12Cpy(dest, src, num) \
|
||||||
{ UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
|
{ UInt32 *d = (UInt32 *)dest; const UInt32 *z = (const UInt32 *)src; UInt32 n = num; \
|
||||||
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while (--n); }
|
do { d[0] = z[0]; d[1] = z[1]; d[2] = z[2]; z += 3; d += 3; } while (--n); }
|
||||||
|
|
||||||
static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
|
static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
|
||||||
{
|
{
|
||||||
@@ -386,7 +386,7 @@ static void RestartModel(CPpmd8 *p)
|
|||||||
|
|
||||||
for (i = m = 0; m < 24; m++)
|
for (i = m = 0; m < 24; m++)
|
||||||
{
|
{
|
||||||
while (p->NS2Indx[i + 3] == m + 3)
|
while (p->NS2Indx[(size_t)i + 3] == m + 3)
|
||||||
i++;
|
i++;
|
||||||
for (k = 0; k < 32; k++)
|
for (k = 0; k < 32; k++)
|
||||||
{
|
{
|
||||||
@@ -772,7 +772,7 @@ static CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, CTX_PTR c)
|
|||||||
if (SUCCESSOR(s) <= upBranch)
|
if (SUCCESSOR(s) <= upBranch)
|
||||||
{
|
{
|
||||||
CTX_PTR successor;
|
CTX_PTR successor;
|
||||||
CPpmd_State *s1 = p->FoundState;
|
CPpmd_State *s2 = p->FoundState;
|
||||||
p->FoundState = s;
|
p->FoundState = s;
|
||||||
|
|
||||||
successor = CreateSuccessors(p, False, NULL, c);
|
successor = CreateSuccessors(p, False, NULL, c);
|
||||||
@@ -780,7 +780,7 @@ static CTX_PTR ReduceOrder(CPpmd8 *p, CPpmd_State *s1, CTX_PTR c)
|
|||||||
SetSuccessor(s, 0);
|
SetSuccessor(s, 0);
|
||||||
else
|
else
|
||||||
SetSuccessor(s, REF(successor));
|
SetSuccessor(s, REF(successor));
|
||||||
p->FoundState = s1;
|
p->FoundState = s2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->OrderFall == 1 && c1 == p->MaxContext)
|
if (p->OrderFall == 1 && c1 == p->MaxContext)
|
||||||
@@ -905,7 +905,7 @@ static void UpdateModel(CPpmd8 *p)
|
|||||||
/* Expand for one UNIT */
|
/* Expand for one UNIT */
|
||||||
unsigned oldNU = (ns1 + 1) >> 1;
|
unsigned oldNU = (ns1 + 1) >> 1;
|
||||||
unsigned i = U2I(oldNU);
|
unsigned i = U2I(oldNU);
|
||||||
if (i != U2I(oldNU + 1))
|
if (i != U2I((size_t)oldNU + 1))
|
||||||
{
|
{
|
||||||
void *ptr = AllocUnits(p, i + 1);
|
void *ptr = AllocUnits(p, i + 1);
|
||||||
void *oldPtr;
|
void *oldPtr;
|
||||||
@@ -924,19 +924,19 @@ static void UpdateModel(CPpmd8 *p)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0);
|
CPpmd_State *s2 = (CPpmd_State*)AllocUnits(p, 0);
|
||||||
if (!s)
|
if (!s2)
|
||||||
{
|
{
|
||||||
RESTORE_MODEL(c, CTX(fSuccessor));
|
RESTORE_MODEL(c, CTX(fSuccessor));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*s = *ONE_STATE(c);
|
*s2 = *ONE_STATE(c);
|
||||||
c->Stats = REF(s);
|
c->Stats = REF(s2);
|
||||||
if (s->Freq < MAX_FREQ / 4 - 1)
|
if (s2->Freq < MAX_FREQ / 4 - 1)
|
||||||
s->Freq <<= 1;
|
s2->Freq <<= 1;
|
||||||
else
|
else
|
||||||
s->Freq = MAX_FREQ - 4;
|
s2->Freq = MAX_FREQ - 4;
|
||||||
c->SummFreq = (UInt16)(s->Freq + p->InitEsc + (ns > 2));
|
c->SummFreq = (UInt16)(s2->Freq + p->InitEsc + (ns > 2));
|
||||||
}
|
}
|
||||||
cf = 2 * fFreq * (c->SummFreq + 6);
|
cf = 2 * fFreq * (c->SummFreq + 6);
|
||||||
sf = (UInt32)s0 + c->SummFreq;
|
sf = (UInt32)s0 + c->SummFreq;
|
||||||
@@ -951,10 +951,10 @@ static void UpdateModel(CPpmd8 *p)
|
|||||||
c->SummFreq = (UInt16)(c->SummFreq + cf);
|
c->SummFreq = (UInt16)(c->SummFreq + cf);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CPpmd_State *s = STATS(c) + ns1 + 1;
|
CPpmd_State *s2 = STATS(c) + ns1 + 1;
|
||||||
SetSuccessor(s, successor);
|
SetSuccessor(s2, successor);
|
||||||
s->Symbol = fSymbol;
|
s2->Symbol = fSymbol;
|
||||||
s->Freq = (Byte)cf;
|
s2->Freq = (Byte)cf;
|
||||||
c->Flags |= flag;
|
c->Flags |= flag;
|
||||||
c->NumStats = (Byte)(ns1 + 1);
|
c->NumStats = (Byte)(ns1 + 1);
|
||||||
}
|
}
|
||||||
@@ -1038,9 +1038,9 @@ CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked1, UInt32 *escFreq)
|
|||||||
CPpmd_See *see;
|
CPpmd_See *see;
|
||||||
if (p->MinContext->NumStats != 0xFF)
|
if (p->MinContext->NumStats != 0xFF)
|
||||||
{
|
{
|
||||||
see = p->See[p->NS2Indx[p->MinContext->NumStats + 2] - 3] +
|
see = p->See[(size_t)(unsigned)p->NS2Indx[(size_t)(unsigned)p->MinContext->NumStats + 2] - 3] +
|
||||||
(p->MinContext->SummFreq > 11 * ((unsigned)p->MinContext->NumStats + 1)) +
|
(p->MinContext->SummFreq > 11 * ((unsigned)p->MinContext->NumStats + 1)) +
|
||||||
2 * (2 * (unsigned)p->MinContext->NumStats <
|
2 * (unsigned)(2 * (unsigned)p->MinContext->NumStats <
|
||||||
((unsigned)SUFFIX(p->MinContext)->NumStats + numMasked1)) +
|
((unsigned)SUFFIX(p->MinContext)->NumStats + numMasked1)) +
|
||||||
p->MinContext->Flags;
|
p->MinContext->Flags;
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd8.h -- PPMdI codec
|
/* Ppmd8.h -- PPMdI codec
|
||||||
2011-01-27 : Igor Pavlov : Public domain
|
2017-04-03 : Igor Pavlov : Public domain
|
||||||
This code is based on:
|
This code is based on:
|
||||||
PPMd var.I (2002): Dmitry Shkarin : Public domain
|
PPMd var.I (2002): Dmitry Shkarin : Public domain
|
||||||
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
|
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
|
||||||
@@ -86,8 +86,8 @@ typedef struct
|
|||||||
} CPpmd8;
|
} CPpmd8;
|
||||||
|
|
||||||
void Ppmd8_Construct(CPpmd8 *p);
|
void Ppmd8_Construct(CPpmd8 *p);
|
||||||
Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc);
|
Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAllocPtr alloc);
|
||||||
void Ppmd8_Free(CPpmd8 *p, ISzAlloc *alloc);
|
void Ppmd8_Free(CPpmd8 *p, ISzAllocPtr alloc);
|
||||||
void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod);
|
void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod);
|
||||||
#define Ppmd8_WasAllocated(p) ((p)->Base != NULL)
|
#define Ppmd8_WasAllocated(p) ((p)->Base != NULL)
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ void Ppmd8_Update2(CPpmd8 *p);
|
|||||||
void Ppmd8_UpdateBin(CPpmd8 *p);
|
void Ppmd8_UpdateBin(CPpmd8 *p);
|
||||||
|
|
||||||
#define Ppmd8_GetBinSumm(p) \
|
#define Ppmd8_GetBinSumm(p) \
|
||||||
&p->BinSumm[p->NS2Indx[Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \
|
&p->BinSumm[p->NS2Indx[(size_t)Ppmd8Context_OneState(p->MinContext)->Freq - 1]][ \
|
||||||
p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \
|
p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \
|
||||||
p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)]
|
p->PrevSuccess + p->MinContext->Flags + ((p->RunLength >> 26) & 0x20)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd8Dec.c -- PPMdI Decoder
|
/* Ppmd8Dec.c -- PPMdI Decoder
|
||||||
2010-04-16 : Igor Pavlov : Public domain
|
2017-04-03 : Igor Pavlov : Public domain
|
||||||
This code is based on:
|
This code is based on:
|
||||||
PPMd var.I (2002): Dmitry Shkarin : Public domain
|
PPMd var.I (2002): Dmitry Shkarin : Public domain
|
||||||
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
|
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
|
||||||
@@ -18,7 +18,7 @@ Bool Ppmd8_RangeDec_Init(CPpmd8 *p)
|
|||||||
p->Range = 0xFFFFFFFF;
|
p->Range = 0xFFFFFFFF;
|
||||||
p->Code = 0;
|
p->Code = 0;
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In);
|
p->Code = (p->Code << 8) | IByteIn_Read(p->Stream.In);
|
||||||
return (p->Code < 0xFFFFFFFF);
|
return (p->Code < 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ static void RangeDec_Decode(CPpmd8 *p, UInt32 start, UInt32 size)
|
|||||||
while ((p->Low ^ (p->Low + p->Range)) < kTop ||
|
while ((p->Low ^ (p->Low + p->Range)) < kTop ||
|
||||||
(p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
|
(p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
|
||||||
{
|
{
|
||||||
p->Code = (p->Code << 8) | p->Stream.In->Read(p->Stream.In);
|
p->Code = (p->Code << 8) | IByteIn_Read(p->Stream.In);
|
||||||
p->Range <<= 8;
|
p->Range <<= 8;
|
||||||
p->Low <<= 8;
|
p->Low <<= 8;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd8Enc.c -- PPMdI Encoder
|
/* Ppmd8Enc.c -- PPMdI Encoder
|
||||||
2010-04-16 : Igor Pavlov : Public domain
|
2017-04-03 : Igor Pavlov : Public domain
|
||||||
This code is based on:
|
This code is based on:
|
||||||
PPMd var.I (2002): Dmitry Shkarin : Public domain
|
PPMd var.I (2002): Dmitry Shkarin : Public domain
|
||||||
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
|
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
|
||||||
@@ -15,7 +15,7 @@ void Ppmd8_RangeEnc_FlushData(CPpmd8 *p)
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i < 4; i++, p->Low <<= 8 )
|
for (i = 0; i < 4; i++, p->Low <<= 8 )
|
||||||
p->Stream.Out->Write(p->Stream.Out, (Byte)(p->Low >> 24));
|
IByteOut_Write(p->Stream.Out, (Byte)(p->Low >> 24));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RangeEnc_Normalize(CPpmd8 *p)
|
static void RangeEnc_Normalize(CPpmd8 *p)
|
||||||
@@ -23,7 +23,7 @@ static void RangeEnc_Normalize(CPpmd8 *p)
|
|||||||
while ((p->Low ^ (p->Low + p->Range)) < kTop ||
|
while ((p->Low ^ (p->Low + p->Range)) < kTop ||
|
||||||
(p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
|
(p->Range < kBot && ((p->Range = (0 - p->Low) & (kBot - 1)), 1)))
|
||||||
{
|
{
|
||||||
p->Stream.Out->Write(p->Stream.Out, (Byte)(p->Low >> 24));
|
IByteOut_Write(p->Stream.Out, (Byte)(p->Low >> 24));
|
||||||
p->Range <<= 8;
|
p->Range <<= 8;
|
||||||
p->Low <<= 8;
|
p->Low <<= 8;
|
||||||
}
|
}
|
||||||
|
|||||||
17
C/Sha1.c
17
C/Sha1.c
@@ -1,5 +1,5 @@
|
|||||||
/* Sha1.c -- SHA-1 Hash
|
/* Sha1.c -- SHA-1 Hash
|
||||||
2016-02-09 : Igor Pavlov : Public domain
|
2017-04-03 : Igor Pavlov : Public domain
|
||||||
This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */
|
This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
@@ -62,8 +62,8 @@ This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ l
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define RX_15 { unsigned i; for (i = 0; i < 15; i += 5) { RX_5(R0, i); } }
|
#define RX_15 { size_t i; for (i = 0; i < 15; i += 5) { RX_5(R0, i); } }
|
||||||
#define RX_20(rx, ii) { unsigned i; i = ii; for (; i < ii + 20; i += 5) { RX_5(rx, i); } }
|
#define RX_20(rx, ii) { size_t i; i = ii; for (; i < ii + 20; i += 5) { RX_5(rx, i); } }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ void Sha1_UpdateBlock_Rar(CSha1 *p, UInt32 *data, int returnRes)
|
|||||||
|
|
||||||
if (returnRes)
|
if (returnRes)
|
||||||
{
|
{
|
||||||
unsigned i;
|
size_t i;
|
||||||
for (i = 0 ; i < SHA1_NUM_BLOCK_WORDS; i++)
|
for (i = 0 ; i < SHA1_NUM_BLOCK_WORDS; i++)
|
||||||
data[i] = W[kNumW - SHA1_NUM_BLOCK_WORDS + i];
|
data[i] = W[kNumW - SHA1_NUM_BLOCK_WORDS + i];
|
||||||
}
|
}
|
||||||
@@ -176,7 +176,7 @@ void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
|
|||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
unsigned i;
|
size_t i;
|
||||||
Sha1_UpdateBlock(p);
|
Sha1_UpdateBlock(p);
|
||||||
if (size < SHA1_BLOCK_SIZE)
|
if (size < SHA1_BLOCK_SIZE)
|
||||||
break;
|
break;
|
||||||
@@ -212,7 +212,7 @@ void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size, int rar350Mode)
|
void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size /* , int rar350Mode */)
|
||||||
{
|
{
|
||||||
int returnRes = False;
|
int returnRes = False;
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size, int rar350Mode)
|
|||||||
Sha1_UpdateBlock_Rar(p, p->buffer, returnRes);
|
Sha1_UpdateBlock_Rar(p, p->buffer, returnRes);
|
||||||
if (returnRes)
|
if (returnRes)
|
||||||
{
|
{
|
||||||
unsigned i;
|
size_t i;
|
||||||
for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++)
|
for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++)
|
||||||
{
|
{
|
||||||
UInt32 d = p->buffer[i];
|
UInt32 d = p->buffer[i];
|
||||||
@@ -246,7 +246,8 @@ void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size, int rar350Mode)
|
|||||||
SetUi32(prev, d);
|
SetUi32(prev, d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
returnRes = rar350Mode;
|
// returnRes = rar350Mode;
|
||||||
|
returnRes = True;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
4
C/Sha1.h
4
C/Sha1.h
@@ -1,5 +1,5 @@
|
|||||||
/* Sha1.h -- SHA-1 Hash
|
/* Sha1.h -- SHA-1 Hash
|
||||||
2015-03-04 : Igor Pavlov : Public domain */
|
2016-05-20 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_SHA1_H
|
#ifndef __7Z_SHA1_H
|
||||||
#define __7Z_SHA1_H
|
#define __7Z_SHA1_H
|
||||||
@@ -27,7 +27,7 @@ void Sha1_GetBlockDigest(CSha1 *p, const UInt32 *data, UInt32 *destDigest);
|
|||||||
void Sha1_Update(CSha1 *p, const Byte *data, size_t size);
|
void Sha1_Update(CSha1 *p, const Byte *data, size_t size);
|
||||||
void Sha1_Final(CSha1 *p, Byte *digest);
|
void Sha1_Final(CSha1 *p, Byte *digest);
|
||||||
|
|
||||||
void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size, int rar350Mode);
|
void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size /* , int rar350Mode */);
|
||||||
|
|
||||||
void Sha1_32_PrepareBlock(const CSha1 *p, UInt32 *block, unsigned size);
|
void Sha1_32_PrepareBlock(const CSha1 *p, UInt32 *block, unsigned size);
|
||||||
void Sha1_32_Update(CSha1 *p, const UInt32 *data, size_t size);
|
void Sha1_32_Update(CSha1 *p, const UInt32 *data, size_t size);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Crypto/Sha256.c -- SHA-256 Hash
|
/* Crypto/Sha256.c -- SHA-256 Hash
|
||||||
2015-11-14 : Igor Pavlov : Public domain
|
2017-04-03 : Igor Pavlov : Public domain
|
||||||
This code is based on public domain code from Wei Dai's Crypto++ library. */
|
This code is based on public domain code from Wei Dai's Crypto++ library. */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
@@ -45,7 +45,7 @@ void Sha256_Init(CSha256 *p)
|
|||||||
#ifdef _SHA256_UNROLL2
|
#ifdef _SHA256_UNROLL2
|
||||||
|
|
||||||
#define R(a,b,c,d,e,f,g,h, i) \
|
#define R(a,b,c,d,e,f,g,h, i) \
|
||||||
h += S1(e) + Ch(e,f,g) + K[(i)+(j)] + (j ? blk2(i) : blk0(i)); \
|
h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + (j ? blk2(i) : blk0(i)); \
|
||||||
d += h; \
|
d += h; \
|
||||||
h += S0(a) + Maj(a, b, c)
|
h += S0(a) + Maj(a, b, c)
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ void Sha256_Init(CSha256 *p)
|
|||||||
#define h(i) T[(7-(i))&7]
|
#define h(i) T[(7-(i))&7]
|
||||||
|
|
||||||
#define R(i) \
|
#define R(i) \
|
||||||
h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+(j)] + (j ? blk2(i) : blk0(i)); \
|
h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+(size_t)(j)] + (j ? blk2(i) : blk0(i)); \
|
||||||
d(i) += h(i); \
|
d(i) += h(i); \
|
||||||
h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) \
|
h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) \
|
||||||
|
|
||||||
|
|||||||
14
C/Threads.c
14
C/Threads.c
@@ -1,5 +1,5 @@
|
|||||||
/* Threads.c -- multithreading library
|
/* Threads.c -- multithreading library
|
||||||
2014-09-21 : Igor Pavlov : Public domain */
|
2017-06-26 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -12,18 +12,20 @@
|
|||||||
static WRes GetError()
|
static WRes GetError()
|
||||||
{
|
{
|
||||||
DWORD res = GetLastError();
|
DWORD res = GetLastError();
|
||||||
return (res) ? (WRes)(res) : 1;
|
return res ? (WRes)res : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); }
|
static WRes HandleToWRes(HANDLE h) { return (h != NULL) ? 0 : GetError(); }
|
||||||
WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
|
static WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
|
||||||
|
|
||||||
WRes HandlePtr_Close(HANDLE *p)
|
WRes HandlePtr_Close(HANDLE *p)
|
||||||
{
|
{
|
||||||
if (*p != NULL)
|
if (*p != NULL)
|
||||||
|
{
|
||||||
if (!CloseHandle(*p))
|
if (!CloseHandle(*p))
|
||||||
return GetError();
|
return GetError();
|
||||||
*p = NULL;
|
*p = NULL;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +51,7 @@ WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
|
|||||||
return HandleToWRes(*p);
|
return HandleToWRes(*p);
|
||||||
}
|
}
|
||||||
|
|
||||||
WRes Event_Create(CEvent *p, BOOL manualReset, int signaled)
|
static WRes Event_Create(CEvent *p, BOOL manualReset, int signaled)
|
||||||
{
|
{
|
||||||
*p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL);
|
*p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL);
|
||||||
return HandleToWRes(*p);
|
return HandleToWRes(*p);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Threads.h -- multithreading library
|
/* Threads.h -- multithreading library
|
||||||
2013-11-12 : Igor Pavlov : Public domain */
|
2017-06-18 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_THREADS_H
|
#ifndef __7Z_THREADS_H
|
||||||
#define __7Z_THREADS_H
|
#define __7Z_THREADS_H
|
||||||
@@ -49,7 +49,8 @@ WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled);
|
|||||||
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);
|
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);
|
||||||
|
|
||||||
typedef HANDLE CSemaphore;
|
typedef HANDLE CSemaphore;
|
||||||
#define Semaphore_Construct(p) (*p) = NULL
|
#define Semaphore_Construct(p) *(p) = NULL
|
||||||
|
#define Semaphore_IsCreated(p) (*(p) != NULL)
|
||||||
#define Semaphore_Close(p) HandlePtr_Close(p)
|
#define Semaphore_Close(p) HandlePtr_Close(p)
|
||||||
#define Semaphore_Wait(p) Handle_WaitObject(*(p))
|
#define Semaphore_Wait(p) Handle_WaitObject(*(p))
|
||||||
WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);
|
WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
/* 7zMain.c - Test application for 7z Decoder
|
/* 7zMain.c - Test application for 7z Decoder
|
||||||
2015-08-02 : Igor Pavlov : Public domain */
|
2017-08-26 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../../CpuArch.h"
|
||||||
|
|
||||||
#include "../../7z.h"
|
#include "../../7z.h"
|
||||||
#include "../../7zAlloc.h"
|
#include "../../7zAlloc.h"
|
||||||
#include "../../7zBuf.h"
|
#include "../../7zBuf.h"
|
||||||
@@ -23,7 +25,17 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
|
||||||
|
#define kInputBufSize ((size_t)1 << 18)
|
||||||
|
|
||||||
|
static const ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||||
|
|
||||||
|
|
||||||
|
static void Print(const char *s)
|
||||||
|
{
|
||||||
|
fputs(s, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int Buf_EnsureSize(CBuf *dest, size_t size)
|
static int Buf_EnsureSize(CBuf *dest, size_t size)
|
||||||
{
|
{
|
||||||
@@ -227,6 +239,7 @@ static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SRes PrintString(const UInt16 *s)
|
static SRes PrintString(const UInt16 *s)
|
||||||
{
|
{
|
||||||
CBuf buf;
|
CBuf buf;
|
||||||
@@ -238,12 +251,12 @@ static SRes PrintString(const UInt16 *s)
|
|||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
fputs((const char *)buf.data, stdout);
|
Print((const char *)buf.data);
|
||||||
Buf_Free(&buf, &g_Alloc);
|
Buf_Free(&buf, &g_Alloc);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UInt64ToStr(UInt64 value, char *s)
|
static void UInt64ToStr(UInt64 value, char *s, int numDigits)
|
||||||
{
|
{
|
||||||
char temp[32];
|
char temp[32];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
@@ -253,6 +266,10 @@ static void UInt64ToStr(UInt64 value, char *s)
|
|||||||
value /= 10;
|
value /= 10;
|
||||||
}
|
}
|
||||||
while (value != 0);
|
while (value != 0);
|
||||||
|
|
||||||
|
for (numDigits -= pos; numDigits > 0; numDigits--)
|
||||||
|
*s++ = ' ';
|
||||||
|
|
||||||
do
|
do
|
||||||
*s++ = temp[--pos];
|
*s++ = temp[--pos];
|
||||||
while (pos);
|
while (pos);
|
||||||
@@ -266,8 +283,10 @@ static char *UIntToStr(char *s, unsigned value, int numDigits)
|
|||||||
do
|
do
|
||||||
temp[pos++] = (char)('0' + (value % 10));
|
temp[pos++] = (char)('0' + (value % 10));
|
||||||
while (value /= 10);
|
while (value /= 10);
|
||||||
|
|
||||||
for (numDigits -= pos; numDigits > 0; numDigits--)
|
for (numDigits -= pos; numDigits > 0; numDigits--)
|
||||||
*s++ = '0';
|
*s++ = '0';
|
||||||
|
|
||||||
do
|
do
|
||||||
*s++ = temp[--pos];
|
*s++ = temp[--pos];
|
||||||
while (pos);
|
while (pos);
|
||||||
@@ -310,10 +329,10 @@ static void ConvertFileTimeToString(const CNtfsFileTime *nt, char *s)
|
|||||||
ms[1] = 29;
|
ms[1] = 29;
|
||||||
for (mon = 0;; mon++)
|
for (mon = 0;; mon++)
|
||||||
{
|
{
|
||||||
unsigned s = ms[mon];
|
unsigned d = ms[mon];
|
||||||
if (v < s)
|
if (v < d)
|
||||||
break;
|
break;
|
||||||
v -= s;
|
v -= d;
|
||||||
}
|
}
|
||||||
s = UIntToStr(s, year, 4); *s++ = '-';
|
s = UIntToStr(s, year, 4); *s++ = '-';
|
||||||
UIntToStr_2(s, mon + 1); s[2] = '-'; s += 3;
|
UIntToStr_2(s, mon + 1); s[2] = '-'; s += 3;
|
||||||
@@ -323,9 +342,16 @@ static void ConvertFileTimeToString(const CNtfsFileTime *nt, char *s)
|
|||||||
UIntToStr_2(s, sec); s[2] = 0;
|
UIntToStr_2(s, sec); s[2] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintError(char *sz)
|
static void PrintLF()
|
||||||
{
|
{
|
||||||
printf("\nERROR: %s\n", sz);
|
Print("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PrintError(char *s)
|
||||||
|
{
|
||||||
|
Print("\nERROR: ");
|
||||||
|
Print(s);
|
||||||
|
PrintLF();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GetAttribString(UInt32 wa, Bool isDir, char *s)
|
static void GetAttribString(UInt32 wa, Bool isDir, char *s)
|
||||||
@@ -343,25 +369,27 @@ static void GetAttribString(UInt32 wa, Bool isDir, char *s)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #define NUM_PARENTS_MAX 128
|
// #define NUM_PARENTS_MAX 128
|
||||||
|
|
||||||
int MY_CDECL main(int numargs, char *args[])
|
int MY_CDECL main(int numargs, char *args[])
|
||||||
{
|
{
|
||||||
CFileInStream archiveStream;
|
|
||||||
CLookToRead lookStream;
|
|
||||||
CSzArEx db;
|
|
||||||
SRes res;
|
|
||||||
ISzAlloc allocImp;
|
ISzAlloc allocImp;
|
||||||
ISzAlloc allocTempImp;
|
ISzAlloc allocTempImp;
|
||||||
|
|
||||||
|
CFileInStream archiveStream;
|
||||||
|
CLookToRead2 lookStream;
|
||||||
|
CSzArEx db;
|
||||||
|
SRes res;
|
||||||
UInt16 *temp = NULL;
|
UInt16 *temp = NULL;
|
||||||
size_t tempSize = 0;
|
size_t tempSize = 0;
|
||||||
// UInt32 parents[NUM_PARENTS_MAX];
|
// UInt32 parents[NUM_PARENTS_MAX];
|
||||||
|
|
||||||
printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n");
|
Print("\n7z Decoder " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n");
|
||||||
|
|
||||||
if (numargs == 1)
|
if (numargs == 1)
|
||||||
{
|
{
|
||||||
printf(
|
Print(
|
||||||
"Usage: 7zDec <command> <archive_name>\n\n"
|
"Usage: 7zDec <command> <archive_name>\n\n"
|
||||||
"<Commands>\n"
|
"<Commands>\n"
|
||||||
" e: Extract files from archive (without using directory names)\n"
|
" e: Extract files from archive (without using directory names)\n"
|
||||||
@@ -370,7 +398,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
" x: eXtract files with full paths\n");
|
" x: eXtract files with full paths\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numargs < 3)
|
if (numargs < 3)
|
||||||
{
|
{
|
||||||
PrintError("incorrect command");
|
PrintError("incorrect command");
|
||||||
@@ -381,11 +409,9 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
|
g_FileCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
allocImp.Alloc = SzAlloc;
|
|
||||||
allocImp.Free = SzFree;
|
|
||||||
|
|
||||||
allocTempImp.Alloc = SzAllocTemp;
|
allocImp = g_Alloc;
|
||||||
allocTempImp.Free = SzFreeTemp;
|
allocTempImp = g_Alloc;
|
||||||
|
|
||||||
#ifdef UNDER_CE
|
#ifdef UNDER_CE
|
||||||
if (InFile_OpenW(&archiveStream.file, L"\test.7z"))
|
if (InFile_OpenW(&archiveStream.file, L"\test.7z"))
|
||||||
@@ -398,16 +424,31 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
FileInStream_CreateVTable(&archiveStream);
|
FileInStream_CreateVTable(&archiveStream);
|
||||||
LookToRead_CreateVTable(&lookStream, False);
|
LookToRead2_CreateVTable(&lookStream, False);
|
||||||
|
lookStream.buf = NULL;
|
||||||
lookStream.realStream = &archiveStream.s;
|
|
||||||
LookToRead_Init(&lookStream);
|
|
||||||
|
|
||||||
|
res = SZ_OK;
|
||||||
|
|
||||||
|
{
|
||||||
|
lookStream.buf = ISzAlloc_Alloc(&allocImp, kInputBufSize);
|
||||||
|
if (!lookStream.buf)
|
||||||
|
res = SZ_ERROR_MEM;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lookStream.bufSize = kInputBufSize;
|
||||||
|
lookStream.realStream = &archiveStream.vt;
|
||||||
|
LookToRead2_Init(&lookStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CrcGenerateTable();
|
CrcGenerateTable();
|
||||||
|
|
||||||
SzArEx_Init(&db);
|
SzArEx_Init(&db);
|
||||||
|
|
||||||
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
res = SzArEx_Open(&db, &lookStream.vt, &allocImp, &allocTempImp);
|
||||||
|
}
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
@@ -477,7 +518,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr);
|
GetAttribString(SzBitWithVals_Check(&db.Attribs, i) ? db.Attribs.Vals[i] : 0, isDir, attr);
|
||||||
|
|
||||||
fileSize = SzArEx_GetFileSize(&db, i);
|
fileSize = SzArEx_GetFileSize(&db, i);
|
||||||
UInt64ToStr(fileSize, s);
|
UInt64ToStr(fileSize, s, 10);
|
||||||
|
|
||||||
if (SzBitWithVals_Check(&db.MTime, i))
|
if (SzBitWithVals_Check(&db.MTime, i))
|
||||||
ConvertFileTimeToString(&db.MTime.Vals[i], t);
|
ConvertFileTimeToString(&db.MTime.Vals[i], t);
|
||||||
@@ -489,29 +530,33 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
t[j] = '\0';
|
t[j] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%s %s %10s ", t, attr, s);
|
Print(t);
|
||||||
|
Print(" ");
|
||||||
|
Print(attr);
|
||||||
|
Print(" ");
|
||||||
|
Print(s);
|
||||||
|
Print(" ");
|
||||||
res = PrintString(temp);
|
res = PrintString(temp);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
if (isDir)
|
if (isDir)
|
||||||
printf("/");
|
Print("/");
|
||||||
printf("\n");
|
PrintLF();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fputs(testCommand ?
|
Print(testCommand ?
|
||||||
"Testing ":
|
"Testing ":
|
||||||
"Extracting ",
|
"Extracting ");
|
||||||
stdout);
|
|
||||||
res = PrintString(temp);
|
res = PrintString(temp);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
printf("/");
|
Print("/");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = SzArEx_Extract(&db, &lookStream.s, i,
|
res = SzArEx_Extract(&db, &lookStream.vt, i,
|
||||||
&blockIndex, &outBuffer, &outBufferSize,
|
&blockIndex, &outBuffer, &outBufferSize,
|
||||||
&offset, &outSizeProcessed,
|
&offset, &outSizeProcessed,
|
||||||
&allocImp, &allocTempImp);
|
&allocImp, &allocTempImp);
|
||||||
@@ -543,7 +588,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
if (isDir)
|
if (isDir)
|
||||||
{
|
{
|
||||||
MyCreateDir(destPath);
|
MyCreateDir(destPath);
|
||||||
printf("\n");
|
PrintLF();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (OutFile_OpenUtf16(&outFile, destPath))
|
else if (OutFile_OpenUtf16(&outFile, destPath))
|
||||||
@@ -571,23 +616,31 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
|
|
||||||
#ifdef USE_WINDOWS_FILE
|
#ifdef USE_WINDOWS_FILE
|
||||||
if (SzBitWithVals_Check(&db.Attribs, i))
|
if (SzBitWithVals_Check(&db.Attribs, i))
|
||||||
SetFileAttributesW(destPath, db.Attribs.Vals[i]);
|
{
|
||||||
|
UInt32 attrib = db.Attribs.Vals[i];
|
||||||
|
/* p7zip stores posix attributes in high 16 bits and adds 0x8000 as marker.
|
||||||
|
We remove posix bits, if we detect posix mode field */
|
||||||
|
if ((attrib & 0xF0000000) != 0)
|
||||||
|
attrib &= 0x7FFF;
|
||||||
|
SetFileAttributesW(destPath, attrib);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
printf("\n");
|
PrintLF();
|
||||||
}
|
}
|
||||||
IAlloc_Free(&allocImp, outBuffer);
|
ISzAlloc_Free(&allocImp, outBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SzArEx_Free(&db, &allocImp);
|
|
||||||
SzFree(NULL, temp);
|
SzFree(NULL, temp);
|
||||||
|
SzArEx_Free(&db, &allocImp);
|
||||||
|
ISzAlloc_Free(&allocImp, lookStream.buf);
|
||||||
|
|
||||||
File_Close(&archiveStream.file);
|
File_Close(&archiveStream.file);
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
printf("\nEverything is Ok\n");
|
Print("\nEverything is Ok\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,7 +651,11 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
else if (res == SZ_ERROR_CRC)
|
else if (res == SZ_ERROR_CRC)
|
||||||
PrintError("CRC error");
|
PrintError("CRC error");
|
||||||
else
|
else
|
||||||
printf("\nERROR #%d\n", res);
|
{
|
||||||
|
char s[32];
|
||||||
|
UInt64ToStr(res, s, 0);
|
||||||
|
PrintError(s);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* 7zipInstall.c - 7-Zip Installer
|
/* 7zipInstall.c - 7-Zip Installer
|
||||||
2015-12-09 : Igor Pavlov : Public domain */
|
2017-08-28 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -21,12 +21,26 @@
|
|||||||
#include "../../7zFile.h"
|
#include "../../7zFile.h"
|
||||||
#include "../../7zVersion.h"
|
#include "../../7zVersion.h"
|
||||||
#include "../../CpuArch.h"
|
#include "../../CpuArch.h"
|
||||||
|
#include "../../DllSecur.h"
|
||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
static const WCHAR *k_7zip = L"7-Zip";
|
|
||||||
|
|
||||||
static const WCHAR *k_Reg_Software_7zip = L"Software\\7-Zip";
|
#define wcscat lstrcatW
|
||||||
|
#define wcslen lstrlenW
|
||||||
|
#define wcscpy lstrcpyW
|
||||||
|
#define wcsncpy lstrcpynW
|
||||||
|
|
||||||
|
|
||||||
|
#define kInputBufSize ((size_t)1 << 18)
|
||||||
|
|
||||||
|
|
||||||
|
#define _7ZIP_CUR_VER ((MY_VER_MAJOR << 16) | MY_VER_MINOR)
|
||||||
|
#define _7ZIP_DLL_VER_COMPAT ((16 << 16) | 3)
|
||||||
|
|
||||||
|
static LPCWSTR const k_7zip = L"7-Zip";
|
||||||
|
|
||||||
|
static LPCWSTR const k_Reg_Software_7zip = L"Software\\7-Zip";
|
||||||
|
|
||||||
// #define _64BIT_INSTALLER 1
|
// #define _64BIT_INSTALLER 1
|
||||||
|
|
||||||
@@ -42,13 +56,13 @@ static const WCHAR *k_Reg_Software_7zip = L"Software\\7-Zip";
|
|||||||
#define k_7zip_with_Ver k_7zip_with_Ver_base
|
#define k_7zip_with_Ver k_7zip_with_Ver_base
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const WCHAR *k_7zip_with_Ver_str = k_7zip_with_Ver;
|
static LPCWSTR const k_7zip_with_Ver_str = k_7zip_with_Ver;
|
||||||
|
|
||||||
static const WCHAR *k_7zip_Setup = k_7zip_with_Ver L" Setup";
|
static LPCWSTR const k_7zip_Setup = k_7zip_with_Ver L" Setup";
|
||||||
|
|
||||||
static const WCHAR *k_Reg_Path = L"Path";
|
static LPCWSTR const k_Reg_Path = L"Path";
|
||||||
|
|
||||||
static const WCHAR *k_Reg_Path32 = L"Path"
|
static LPCWSTR const k_Reg_Path32 = L"Path"
|
||||||
#ifdef _64BIT_INSTALLER
|
#ifdef _64BIT_INSTALLER
|
||||||
L"64"
|
L"64"
|
||||||
#else
|
#else
|
||||||
@@ -70,8 +84,8 @@ static const WCHAR *k_Reg_Path32 = L"Path"
|
|||||||
|
|
||||||
#define k_7zip_CLSID L"{23170F69-40C1-278A-1000-000100020000}"
|
#define k_7zip_CLSID L"{23170F69-40C1-278A-1000-000100020000}"
|
||||||
|
|
||||||
static const WCHAR *k_Reg_CLSID_7zip = L"CLSID\\" k_7zip_CLSID;
|
static LPCWSTR const k_Reg_CLSID_7zip = L"CLSID\\" k_7zip_CLSID;
|
||||||
static const WCHAR *k_Reg_CLSID_7zip_Inproc = L"CLSID\\" k_7zip_CLSID L"\\InprocServer32";
|
static LPCWSTR const k_Reg_CLSID_7zip_Inproc = L"CLSID\\" k_7zip_CLSID L"\\InprocServer32";
|
||||||
|
|
||||||
#define g_AllUsers True
|
#define g_AllUsers True
|
||||||
|
|
||||||
@@ -106,13 +120,41 @@ static void PrintErrorMessage(const char *s)
|
|||||||
MessageBoxW(g_HWND, s2, k_7zip_with_Ver_str, MB_ICONERROR);
|
MessageBoxW(g_HWND, s2, k_7zip_with_Ver_str, MB_ICONERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static WRes MyCreateDir(const WCHAR *name)
|
|
||||||
|
static DWORD GetFileVersion(LPCWSTR s)
|
||||||
|
{
|
||||||
|
DWORD size = 0;
|
||||||
|
BYTE *vi = NULL;
|
||||||
|
DWORD version = 0;
|
||||||
|
|
||||||
|
size = GetFileVersionInfoSizeW(s, NULL);
|
||||||
|
if (size == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
vi = malloc(size);
|
||||||
|
if (!vi)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (GetFileVersionInfoW(s, 0, size, vi))
|
||||||
|
{
|
||||||
|
VS_FIXEDFILEINFO *fi = NULL;
|
||||||
|
UINT fiLen = 0;
|
||||||
|
if (VerQueryValueW(vi, L"\\", (LPVOID *)&fi, &fiLen))
|
||||||
|
version = fi->dwFileVersionMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(vi);
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static WRes MyCreateDir(LPCWSTR name)
|
||||||
{
|
{
|
||||||
return CreateDirectoryW(name, NULL) ? 0 : GetLastError();
|
return CreateDirectoryW(name, NULL) ? 0 : GetLastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IS_SEPAR(c) (c == WCHAR_PATH_SEPARATOR)
|
#define IS_SEPAR(c) (c == WCHAR_PATH_SEPARATOR)
|
||||||
#define IS_LETTER_CHAR(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z')
|
#define IS_LETTER_CHAR(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
|
||||||
#define IS_DRIVE_PATH(s) (IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(s[2]))
|
#define IS_DRIVE_PATH(s) (IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(s[2]))
|
||||||
|
|
||||||
static int ReverseFind_PathSepar(const wchar_t *s)
|
static int ReverseFind_PathSepar(const wchar_t *s)
|
||||||
@@ -454,7 +496,7 @@ static wchar_t MyWCharLower_Ascii(wchar_t c)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const WCHAR *FindSubString(const WCHAR *s1, const char *s2)
|
static LPCWSTR FindSubString(LPCWSTR s1, const char *s2)
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@@ -701,8 +743,8 @@ static void SetShellProgramsGroup(HWND hwndOwner)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static const WCHAR *k_Shell_Approved = L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved";
|
static LPCWSTR const k_Shell_Approved = L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved";
|
||||||
static const WCHAR *k_7zip_ShellExtension = L"7-Zip Shell Extension";
|
static LPCWSTR const k_7zip_ShellExtension = L"7-Zip Shell Extension";
|
||||||
|
|
||||||
static void WriteCLSID()
|
static void WriteCLSID()
|
||||||
{
|
{
|
||||||
@@ -746,7 +788,7 @@ static void WriteCLSID()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const WCHAR * const k_ShellEx_Items[] =
|
static LPCWSTR const k_ShellEx_Items[] =
|
||||||
{
|
{
|
||||||
L"*\\shellex\\ContextMenuHandlers"
|
L"*\\shellex\\ContextMenuHandlers"
|
||||||
, L"Directory\\shellex\\ContextMenuHandlers"
|
, L"Directory\\shellex\\ContextMenuHandlers"
|
||||||
@@ -876,6 +918,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
UNUSED_VAR(nCmdShow)
|
UNUSED_VAR(nCmdShow)
|
||||||
|
|
||||||
#ifndef UNDER_CE
|
#ifndef UNDER_CE
|
||||||
|
LoadSecurityDlls();
|
||||||
CoInitialize(NULL);
|
CoInitialize(NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -914,7 +957,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
num = s2 - s;
|
num = s2 - s;
|
||||||
if (num > MAX_PATH)
|
if (num > MAX_PATH)
|
||||||
num = MAX_PATH;
|
num = MAX_PATH;
|
||||||
wcsncpy(path, s, num);
|
wcsncpy(path, s, (unsigned)num);
|
||||||
RemoveQuotes(path);
|
RemoveQuotes(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1057,6 +1100,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Bool GetErrorMessage(DWORD errorCode, WCHAR *message)
|
static Bool GetErrorMessage(DWORD errorCode, WCHAR *message)
|
||||||
{
|
{
|
||||||
LPVOID msgBuf;
|
LPVOID msgBuf;
|
||||||
@@ -1071,10 +1115,12 @@ static Bool GetErrorMessage(DWORD errorCode, WCHAR *message)
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int Install()
|
static int Install()
|
||||||
{
|
{
|
||||||
CFileInStream archiveStream;
|
CFileInStream archiveStream;
|
||||||
CLookToRead lookStream;
|
CLookToRead2 lookStream;
|
||||||
CSzArEx db;
|
CSzArEx db;
|
||||||
|
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
@@ -1085,7 +1131,7 @@ static int Install()
|
|||||||
ISzAlloc allocTempImp;
|
ISzAlloc allocTempImp;
|
||||||
WCHAR sfxPath[MAX_PATH + 2];
|
WCHAR sfxPath[MAX_PATH + 2];
|
||||||
|
|
||||||
Bool needReboot = False;
|
int needRebootLevel = 0;
|
||||||
|
|
||||||
allocImp.Alloc = SzAlloc;
|
allocImp.Alloc = SzAlloc;
|
||||||
allocImp.Free = SzFree;
|
allocImp.Free = SzFree;
|
||||||
@@ -1125,7 +1171,8 @@ if (res == SZ_OK)
|
|||||||
}
|
}
|
||||||
|
|
||||||
FileInStream_CreateVTable(&archiveStream);
|
FileInStream_CreateVTable(&archiveStream);
|
||||||
LookToRead_CreateVTable(&lookStream, False);
|
LookToRead2_CreateVTable(&lookStream, False);
|
||||||
|
lookStream.buf = NULL;
|
||||||
|
|
||||||
{
|
{
|
||||||
// Remove post spaces
|
// Remove post spaces
|
||||||
@@ -1148,17 +1195,28 @@ if (res == SZ_OK)
|
|||||||
winRes = CreateComplexDir();
|
winRes = CreateComplexDir();
|
||||||
|
|
||||||
if (winRes != 0)
|
if (winRes != 0)
|
||||||
res = E_FAIL;
|
res = SZ_ERROR_FAIL;
|
||||||
|
|
||||||
pathLen = wcslen(path);
|
pathLen = wcslen(path);
|
||||||
|
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
lookStream.buf = ISzAlloc_Alloc(&allocImp, kInputBufSize);
|
||||||
|
if (!lookStream.buf)
|
||||||
|
res = SZ_ERROR_MEM;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lookStream.bufSize = kInputBufSize;
|
||||||
|
lookStream.realStream = &archiveStream.vt;
|
||||||
|
LookToRead2_Init(&lookStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SzArEx_Init(&db);
|
SzArEx_Init(&db);
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
lookStream.realStream = &archiveStream.s;
|
res = SzArEx_Open(&db, &lookStream.vt, &allocImp, &allocTempImp);
|
||||||
LookToRead_Init(&lookStream);
|
|
||||||
|
|
||||||
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
@@ -1220,7 +1278,7 @@ if (res == SZ_OK)
|
|||||||
SetWindowTextW(g_InfoLine_HWND, temp);
|
SetWindowTextW(g_InfoLine_HWND, temp);
|
||||||
|
|
||||||
{
|
{
|
||||||
res = SzArEx_Extract(&db, &lookStream.s, i,
|
res = SzArEx_Extract(&db, &lookStream.vt, i,
|
||||||
&blockIndex, &outBuf, &outBufSize,
|
&blockIndex, &outBuf, &outBufSize,
|
||||||
&offset, &outSizeProcessed,
|
&offset, &outSizeProcessed,
|
||||||
&allocImp, &allocTempImp);
|
&allocImp, &allocTempImp);
|
||||||
@@ -1234,6 +1292,7 @@ if (res == SZ_OK)
|
|||||||
size_t j;
|
size_t j;
|
||||||
// size_t nameStartPos = 0;
|
// size_t nameStartPos = 0;
|
||||||
UInt32 tempIndex = 0;
|
UInt32 tempIndex = 0;
|
||||||
|
int fileLevel = 1 << 2;
|
||||||
WCHAR origPath[MAX_PATH * 2 + 10];
|
WCHAR origPath[MAX_PATH * 2 + 10];
|
||||||
|
|
||||||
for (j = 0; temp[j] != 0; j++)
|
for (j = 0; temp[j] != 0; j++)
|
||||||
@@ -1287,13 +1346,20 @@ if (res == SZ_OK)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tempIndex != 0
|
if (tempIndex != 0)
|
||||||
|| FindSubString(temp, "7-zip.dll")
|
{
|
||||||
|
tempIndex++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FindSubString(temp, "7-zip.dll")
|
||||||
#ifdef _64BIT_INSTALLER
|
#ifdef _64BIT_INSTALLER
|
||||||
|| FindSubString(temp, "7-zip32.dll")
|
|| FindSubString(temp, "7-zip32.dll")
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
DWORD ver = GetFileVersion(path);
|
||||||
|
fileLevel = ((ver < _7ZIP_DLL_VER_COMPAT || ver > _7ZIP_CUR_VER) ? 2 : 1);
|
||||||
tempIndex++;
|
tempIndex++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1337,7 +1403,7 @@ if (res == SZ_OK)
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (res = S_OK)
|
// if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
processedSize = outSizeProcessed;
|
processedSize = outSizeProcessed;
|
||||||
winRes = File_Write(&outFile, outBuf + offset, &processedSize);
|
winRes = File_Write(&outFile, outBuf + offset, &processedSize);
|
||||||
@@ -1386,14 +1452,14 @@ if (res == SZ_OK)
|
|||||||
winRes = GetLastError();
|
winRes = GetLastError();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
needReboot = True;
|
needRebootLevel |= fileLevel;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IAlloc_Free(&allocImp, outBuf);
|
ISzAlloc_Free(&allocImp, outBuf);
|
||||||
|
|
||||||
if (!g_SilentMode)
|
if (!g_SilentMode)
|
||||||
SendMessage(g_Progress_HWND, PBM_SETPOS, i, 0);
|
SendMessage(g_Progress_HWND, PBM_SETPOS, i, 0);
|
||||||
@@ -1414,6 +1480,8 @@ if (res == SZ_OK)
|
|||||||
|
|
||||||
SzArEx_Free(&db, &allocImp);
|
SzArEx_Free(&db, &allocImp);
|
||||||
|
|
||||||
|
ISzAlloc_Free(&allocImp, lookStream.buf);
|
||||||
|
|
||||||
File_Close(&archiveStream.file);
|
File_Close(&archiveStream.file);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1423,7 +1491,7 @@ if (res == SZ_OK)
|
|||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
if (!g_SilentMode && needReboot)
|
if (!g_SilentMode && needRebootLevel > 1)
|
||||||
{
|
{
|
||||||
if (MessageBoxW(g_HWND, L"You must restart your system to complete the installation.\nRestart now?",
|
if (MessageBoxW(g_HWND, L"You must restart your system to complete the installation.\nRestart now?",
|
||||||
k_7zip_Setup, MB_YESNO | MB_DEFBUTTON2) == IDYES)
|
k_7zip_Setup, MB_YESNO | MB_DEFBUTTON2) == IDYES)
|
||||||
|
|||||||
@@ -40,9 +40,10 @@ RSC=rc.exe
|
|||||||
# PROP Use_Debug_Libraries 0
|
# PROP Use_Debug_Libraries 0
|
||||||
# PROP Output_Dir "Release"
|
# PROP Output_Dir "Release"
|
||||||
# PROP Intermediate_Dir "Release"
|
# PROP Intermediate_Dir "Release"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||||
# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /Yu"Precomp.h" /FD /c
|
# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /Yu"Precomp.h" /FD /c
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||||
@@ -52,7 +53,7 @@ BSC32=bscmake.exe
|
|||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib /nologo /subsystem:windows /machine:I386
|
||||||
|
|
||||||
!ELSEIF "$(CFG)" == "7zipInstall - Win32 Debug"
|
!ELSEIF "$(CFG)" == "7zipInstall - Win32 Debug"
|
||||||
|
|
||||||
@@ -78,7 +79,7 @@ BSC32=bscmake.exe
|
|||||||
# ADD BSC32 /nologo
|
# ADD BSC32 /nologo
|
||||||
LINK32=link.exe
|
LINK32=link.exe
|
||||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|
||||||
@@ -191,6 +192,14 @@ SOURCE=..\..\Delta.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\DllSecur.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\DllSecur.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\Lzma2Dec.c
|
SOURCE=..\..\Lzma2Dec.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
PROG = 7zipInstall.exe
|
PROG = 7zipInstall.exe
|
||||||
|
|
||||||
|
LIBS = $(LIBS) version.lib
|
||||||
|
|
||||||
!IFDEF _64BIT_INSTALLER
|
!IFDEF _64BIT_INSTALLER
|
||||||
CFLAGS = $(CFLAGS) -D_64BIT_INSTALLER
|
CFLAGS = $(CFLAGS) -D_64BIT_INSTALLER
|
||||||
!ENDIF
|
!ENDIF
|
||||||
@@ -25,6 +27,7 @@ C_OBJS = \
|
|||||||
$O\7zStream.obj \
|
$O\7zStream.obj \
|
||||||
$O\Bcj2.obj \
|
$O\Bcj2.obj \
|
||||||
$O\CpuArch.obj \
|
$O\CpuArch.obj \
|
||||||
|
$O\DllSecur.obj \
|
||||||
$O\LzmaDec.obj \
|
$O\LzmaDec.obj \
|
||||||
|
|
||||||
OBJS = \
|
OBJS = \
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* 7zipUninstall.c - 7-Zip Uninstaller
|
/* 7zipUninstall.c - 7-Zip Uninstaller
|
||||||
2015-12-26 : Igor Pavlov : Public domain */
|
2017-04-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
#define LLL_(quote) L##quote
|
#define LLL_(quote) L##quote
|
||||||
#define LLL(quote) LLL_(quote)
|
#define LLL(quote) LLL_(quote)
|
||||||
|
|
||||||
// static const WCHAR *k_7zip = L"7-Zip";
|
// static const WCHAR * const k_7zip = L"7-Zip";
|
||||||
|
|
||||||
// #define _64BIT_INSTALLER 1
|
// #define _64BIT_INSTALLER 1
|
||||||
|
|
||||||
@@ -36,13 +36,13 @@
|
|||||||
#define k_7zip_with_Ver k_7zip_with_Ver_base
|
#define k_7zip_with_Ver k_7zip_with_Ver_base
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// static const WCHAR *k_7zip_with_Ver_str = k_7zip_with_Ver;
|
// static const WCHAR * const k_7zip_with_Ver_str = k_7zip_with_Ver;
|
||||||
|
|
||||||
static const WCHAR *k_Reg_Software_7zip = L"Software\\7-Zip";
|
static const WCHAR * const k_Reg_Software_7zip = L"Software\\7-Zip";
|
||||||
|
|
||||||
static const WCHAR *k_Reg_Path = L"Path";
|
static const WCHAR * const k_Reg_Path = L"Path";
|
||||||
|
|
||||||
static const WCHAR *k_Reg_Path32 = L"Path"
|
static const WCHAR * const k_Reg_Path32 = L"Path"
|
||||||
#ifdef _64BIT_INSTALLER
|
#ifdef _64BIT_INSTALLER
|
||||||
L"64"
|
L"64"
|
||||||
#else
|
#else
|
||||||
@@ -64,8 +64,8 @@ static const WCHAR *k_Reg_Path32 = L"Path"
|
|||||||
|
|
||||||
#define k_7zip_CLSID L"{23170F69-40C1-278A-1000-000100020000}"
|
#define k_7zip_CLSID L"{23170F69-40C1-278A-1000-000100020000}"
|
||||||
|
|
||||||
static const WCHAR *k_Reg_CLSID_7zip = L"CLSID\\" k_7zip_CLSID;
|
static const WCHAR * const k_Reg_CLSID_7zip = L"CLSID\\" k_7zip_CLSID;
|
||||||
static const WCHAR *k_Reg_CLSID_7zip_Inproc = L"CLSID\\" k_7zip_CLSID L"\\InprocServer32";
|
static const WCHAR * const k_Reg_CLSID_7zip_Inproc = L"CLSID\\" k_7zip_CLSID L"\\InprocServer32";
|
||||||
|
|
||||||
|
|
||||||
#define g_AllUsers True
|
#define g_AllUsers True
|
||||||
@@ -90,7 +90,7 @@ static WCHAR tempPath[MAX_PATH * 2 + 40];
|
|||||||
static WCHAR cmdLine[MAX_PATH * 3 + 40];
|
static WCHAR cmdLine[MAX_PATH * 3 + 40];
|
||||||
static WCHAR copyPath[MAX_PATH * 2 + 40];
|
static WCHAR copyPath[MAX_PATH * 2 + 40];
|
||||||
|
|
||||||
static const WCHAR *kUninstallExe = L"Uninstall.exe";
|
static const WCHAR * const kUninstallExe = L"Uninstall.exe";
|
||||||
|
|
||||||
#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) -= 0x20 : (c)))
|
#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) -= 0x20 : (c)))
|
||||||
|
|
||||||
@@ -340,11 +340,11 @@ static const WCHAR * const k_ShellEx_Items[] =
|
|||||||
, L"Drive\\shellex\\DragDropHandlers"
|
, L"Drive\\shellex\\DragDropHandlers"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const WCHAR *k_Shell_Approved = L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved";
|
static const WCHAR * const k_Shell_Approved = L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved";
|
||||||
|
|
||||||
static const WCHAR *k_AppPaths_7zFm = L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\7zFM.exe";
|
static const WCHAR * const k_AppPaths_7zFm = L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\7zFM.exe";
|
||||||
#define k_REG_Uninstall L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
|
#define k_REG_Uninstall L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
|
||||||
static const WCHAR *k_Uninstall_7zip = k_REG_Uninstall L"7-Zip";
|
static const WCHAR * const k_Uninstall_7zip = k_REG_Uninstall L"7-Zip";
|
||||||
|
|
||||||
|
|
||||||
static Bool AreEqual_Path_PrefixName(const wchar_t *s, const wchar_t *prefix, const wchar_t *name)
|
static Bool AreEqual_Path_PrefixName(const wchar_t *s, const wchar_t *prefix, const wchar_t *name)
|
||||||
@@ -362,9 +362,11 @@ static void WriteCLSID()
|
|||||||
{
|
{
|
||||||
if (AreEqual_Path_PrefixName(s, path, L"7-zip.dll"))
|
if (AreEqual_Path_PrefixName(s, path, L"7-zip.dll"))
|
||||||
{
|
{
|
||||||
LONG res = MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc);
|
{
|
||||||
if (res == ERROR_SUCCESS)
|
LONG res = MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc);
|
||||||
MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip);
|
if (res == ERROR_SUCCESS)
|
||||||
|
MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@@ -397,9 +399,11 @@ static void WriteCLSID()
|
|||||||
{
|
{
|
||||||
if (AreEqual_Path_PrefixName(s, path, L"7-zip32.dll"))
|
if (AreEqual_Path_PrefixName(s, path, L"7-zip32.dll"))
|
||||||
{
|
{
|
||||||
LONG res = MyRegistry_DeleteKey_32(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc);
|
{
|
||||||
if (res == ERROR_SUCCESS)
|
LONG res = MyRegistry_DeleteKey_32(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip_Inproc);
|
||||||
MyRegistry_DeleteKey_32(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip);
|
if (res == ERROR_SUCCESS)
|
||||||
|
MyRegistry_DeleteKey_32(HKEY_CLASSES_ROOT, k_Reg_CLSID_7zip);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@@ -552,7 +556,7 @@ static BOOL RemoveDir()
|
|||||||
|
|
||||||
#define NUM_FILES (NUM_LANG_TXT_FILES + 1 + 13 + NUM_EXTRA_FILES_64BIT)
|
#define NUM_FILES (NUM_LANG_TXT_FILES + 1 + 13 + NUM_EXTRA_FILES_64BIT)
|
||||||
|
|
||||||
static const char *k_Names =
|
static const char * const k_Names =
|
||||||
"af an ar ast az ba be bg bn br ca co cs cy da de el eo es et eu ext"
|
"af an ar ast az ba be bg bn br ca co cs cy da de el eo es et eu ext"
|
||||||
" fa fi fr fur fy ga gl gu he hi hr hu hy id io is it ja ka kaa kk ko ku ku-ckb ky"
|
" fa fi fr fur fy ga gl gu he hi hr hu hy id io is it ja ka kaa kk ko ku ku-ckb ky"
|
||||||
" lij lt lv mk mn mng mng2 mr ms nb ne nl nn pa-in pl ps pt pt-br ro ru"
|
" lij lt lv mk mn mng mng2 mr ms nb ne nl nn pa-in pl ps pt pt-br ro ru"
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ RSC=rc.exe
|
|||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||||
# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /Yu"Precomp.h" /FD /c
|
# ADD CPP /nologo /Gr /MD /W4 /WX /GX /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /FAcs /Yu"Precomp.h" /FD /GF /c
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaUtil.c -- Test application for LZMA compression
|
/* LzmaUtil.c -- Test application for LZMA compression
|
||||||
2015-11-08 : Igor Pavlov : Public domain */
|
2017-04-27 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "../../Precomp.h"
|
#include "../../Precomp.h"
|
||||||
|
|
||||||
@@ -7,26 +7,29 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../../CpuArch.h"
|
||||||
|
|
||||||
#include "../../Alloc.h"
|
#include "../../Alloc.h"
|
||||||
#include "../../7zFile.h"
|
#include "../../7zFile.h"
|
||||||
#include "../../7zVersion.h"
|
#include "../../7zVersion.h"
|
||||||
#include "../../LzmaDec.h"
|
#include "../../LzmaDec.h"
|
||||||
#include "../../LzmaEnc.h"
|
#include "../../LzmaEnc.h"
|
||||||
|
|
||||||
const char *kCantReadMessage = "Can not read input file";
|
static const char * const kCantReadMessage = "Can not read input file";
|
||||||
const char *kCantWriteMessage = "Can not write output file";
|
static const char * const kCantWriteMessage = "Can not write output file";
|
||||||
const char *kCantAllocateMessage = "Can not allocate memory";
|
static const char * const kCantAllocateMessage = "Can not allocate memory";
|
||||||
const char *kDataErrorMessage = "Data error";
|
static const char * const kDataErrorMessage = "Data error";
|
||||||
|
|
||||||
void PrintHelp(char *buffer)
|
static void PrintHelp(char *buffer)
|
||||||
{
|
{
|
||||||
strcat(buffer, "\nLZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n"
|
strcat(buffer,
|
||||||
"\nUsage: lzma <e|d> inputFile outputFile\n"
|
"\nLZMA-C " MY_VERSION_CPU " : " MY_COPYRIGHT_DATE "\n\n"
|
||||||
" e: encode file\n"
|
"Usage: lzma <e|d> inputFile outputFile\n"
|
||||||
" d: decode file\n");
|
" e: encode file\n"
|
||||||
|
" d: decode file\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int PrintError(char *buffer, const char *message)
|
static int PrintError(char *buffer, const char *message)
|
||||||
{
|
{
|
||||||
strcat(buffer, "\nError: ");
|
strcat(buffer, "\nError: ");
|
||||||
strcat(buffer, message);
|
strcat(buffer, message);
|
||||||
@@ -34,20 +37,22 @@ int PrintError(char *buffer, const char *message)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PrintErrorNumber(char *buffer, SRes val)
|
static int PrintErrorNumber(char *buffer, SRes val)
|
||||||
{
|
{
|
||||||
sprintf(buffer + strlen(buffer), "\nError code: %x\n", (unsigned)val);
|
sprintf(buffer + strlen(buffer), "\nError code: %x\n", (unsigned)val);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PrintUserError(char *buffer)
|
static int PrintUserError(char *buffer)
|
||||||
{
|
{
|
||||||
return PrintError(buffer, "Incorrect command");
|
return PrintError(buffer, "Incorrect command");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define IN_BUF_SIZE (1 << 16)
|
#define IN_BUF_SIZE (1 << 16)
|
||||||
#define OUT_BUF_SIZE (1 << 16)
|
#define OUT_BUF_SIZE (1 << 16)
|
||||||
|
|
||||||
|
|
||||||
static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream,
|
static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||||
UInt64 unpackSize)
|
UInt64 unpackSize)
|
||||||
{
|
{
|
||||||
@@ -101,6 +106,7 @@ static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream)
|
static SRes Decode(ISeqOutStream *outStream, ISeqInStream *inStream)
|
||||||
{
|
{
|
||||||
UInt64 unpackSize;
|
UInt64 unpackSize;
|
||||||
@@ -163,7 +169,8 @@ static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 file
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main2(int numArgs, const char *args[], char *rs)
|
|
||||||
|
static int main2(int numArgs, const char *args[], char *rs)
|
||||||
{
|
{
|
||||||
CFileSeqInStream inStream;
|
CFileSeqInStream inStream;
|
||||||
CFileOutStream outStream;
|
CFileOutStream outStream;
|
||||||
@@ -215,11 +222,11 @@ int main2(int numArgs, const char *args[], char *rs)
|
|||||||
{
|
{
|
||||||
UInt64 fileSize;
|
UInt64 fileSize;
|
||||||
File_GetLength(&inStream.file, &fileSize);
|
File_GetLength(&inStream.file, &fileSize);
|
||||||
res = Encode(&outStream.s, &inStream.s, fileSize, rs);
|
res = Encode(&outStream.vt, &inStream.vt, fileSize, rs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res = Decode(&outStream.s, useOutFile ? &inStream.s : NULL);
|
res = Decode(&outStream.vt, useOutFile ? &inStream.vt : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useOutFile)
|
if (useOutFile)
|
||||||
@@ -241,6 +248,7 @@ int main2(int numArgs, const char *args[], char *rs)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int MY_CDECL main(int numArgs, const char *args[])
|
int MY_CDECL main(int numArgs, const char *args[])
|
||||||
{
|
{
|
||||||
char rs[800] = { 0 };
|
char rs[800] = { 0 };
|
||||||
|
|||||||
@@ -98,6 +98,10 @@ SOURCE=..\..\7zStream.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7zTypes.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\7zVersion.h
|
SOURCE=..\..\7zVersion.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -160,9 +164,5 @@ SOURCE=..\..\Threads.c
|
|||||||
|
|
||||||
SOURCE=..\..\Threads.h
|
SOURCE=..\..\Threads.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=..\..\Types.h
|
|
||||||
# End Source File
|
|
||||||
# End Target
|
# End Target
|
||||||
# End Project
|
# End Project
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* SfxSetup.c - 7z SFX Setup
|
/* SfxSetup.c - 7z SFX Setup
|
||||||
2015-11-08 : Igor Pavlov : Public domain */
|
2017-04-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -20,9 +20,12 @@
|
|||||||
#include "../../7zCrc.h"
|
#include "../../7zCrc.h"
|
||||||
#include "../../7zFile.h"
|
#include "../../7zFile.h"
|
||||||
#include "../../CpuArch.h"
|
#include "../../CpuArch.h"
|
||||||
|
#include "../../DllSecur.h"
|
||||||
|
|
||||||
#define k_EXE_ExtIndex 2
|
#define k_EXE_ExtIndex 2
|
||||||
|
|
||||||
|
#define kInputBufSize ((size_t)1 << 18)
|
||||||
|
|
||||||
static const char * const kExts[] =
|
static const char * const kExts[] =
|
||||||
{
|
{
|
||||||
"bat"
|
"bat"
|
||||||
@@ -237,7 +240,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
CFileInStream archiveStream;
|
CFileInStream archiveStream;
|
||||||
CLookToRead lookStream;
|
CLookToRead2 lookStream;
|
||||||
CSzArEx db;
|
CSzArEx db;
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
ISzAlloc allocImp;
|
ISzAlloc allocImp;
|
||||||
@@ -254,6 +257,8 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
Bool useShellExecute = True;
|
Bool useShellExecute = True;
|
||||||
DWORD exitCode = 0;
|
DWORD exitCode = 0;
|
||||||
|
|
||||||
|
LoadSecurityDlls();
|
||||||
|
|
||||||
#ifdef _CONSOLE
|
#ifdef _CONSOLE
|
||||||
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
|
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
|
||||||
#else
|
#else
|
||||||
@@ -272,7 +277,8 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
allocTempImp.Free = SzFreeTemp;
|
allocTempImp.Free = SzFreeTemp;
|
||||||
|
|
||||||
FileInStream_CreateVTable(&archiveStream);
|
FileInStream_CreateVTable(&archiveStream);
|
||||||
LookToRead_CreateVTable(&lookStream, False);
|
LookToRead2_CreateVTable(&lookStream, False);
|
||||||
|
lookStream.buf = NULL;
|
||||||
|
|
||||||
winRes = GetModuleFileNameW(NULL, sfxPath, MAX_PATH);
|
winRes = GetModuleFileNameW(NULL, sfxPath, MAX_PATH);
|
||||||
if (winRes == 0 || winRes > MAX_PATH)
|
if (winRes == 0 || winRes > MAX_PATH)
|
||||||
@@ -373,14 +379,22 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
lookStream.realStream = &archiveStream.s;
|
lookStream.buf = ISzAlloc_Alloc(&allocImp, kInputBufSize);
|
||||||
LookToRead_Init(&lookStream);
|
if (!lookStream.buf)
|
||||||
|
res = SZ_ERROR_MEM;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lookStream.bufSize = kInputBufSize;
|
||||||
|
lookStream.realStream = &archiveStream.vt;
|
||||||
|
LookToRead2_Init(&lookStream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SzArEx_Init(&db);
|
SzArEx_Init(&db);
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
|
res = SzArEx_Open(&db, &lookStream.vt, &allocImp, &allocTempImp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
@@ -396,11 +410,9 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
{
|
{
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
size_t outSizeProcessed = 0;
|
size_t outSizeProcessed = 0;
|
||||||
size_t len;
|
|
||||||
WCHAR *temp;
|
WCHAR *temp;
|
||||||
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
|
|
||||||
|
if (SzArEx_GetFileNameUtf16(&db, i, NULL) >= MAX_PATH)
|
||||||
if (len >= MAX_PATH)
|
|
||||||
{
|
{
|
||||||
res = SZ_ERROR_FAIL;
|
res = SZ_ERROR_FAIL;
|
||||||
break;
|
break;
|
||||||
@@ -410,7 +422,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
|
|
||||||
SzArEx_GetFileNameUtf16(&db, i, temp);
|
SzArEx_GetFileNameUtf16(&db, i, temp);
|
||||||
{
|
{
|
||||||
res = SzArEx_Extract(&db, &lookStream.s, i,
|
res = SzArEx_Extract(&db, &lookStream.vt, i,
|
||||||
&blockIndex, &outBuffer, &outBufferSize,
|
&blockIndex, &outBuffer, &outBufferSize,
|
||||||
&offset, &outSizeProcessed,
|
&offset, &outSizeProcessed,
|
||||||
&allocImp, &allocTempImp);
|
&allocImp, &allocTempImp);
|
||||||
@@ -521,10 +533,13 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
temp[j] = CHAR_PATH_SEPARATOR;
|
temp[j] = CHAR_PATH_SEPARATOR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IAlloc_Free(&allocImp, outBuffer);
|
ISzAlloc_Free(&allocImp, outBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
SzArEx_Free(&db, &allocImp);
|
SzArEx_Free(&db, &allocImp);
|
||||||
|
|
||||||
|
ISzAlloc_Free(&allocImp, lookStream.buf);
|
||||||
|
|
||||||
File_Close(&archiveStream.file);
|
File_Close(&archiveStream.file);
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
|
|||||||
@@ -187,6 +187,14 @@ SOURCE=..\..\Delta.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\DllSecur.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\DllSecur.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\Lzma2Dec.c
|
SOURCE=..\..\Lzma2Dec.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ C_OBJS = \
|
|||||||
$O\BraIA64.obj \
|
$O\BraIA64.obj \
|
||||||
$O\CpuArch.obj \
|
$O\CpuArch.obj \
|
||||||
$O\Delta.obj \
|
$O\Delta.obj \
|
||||||
|
$O\DllSecur.obj \
|
||||||
$O\Lzma2Dec.obj \
|
$O\Lzma2Dec.obj \
|
||||||
$O\LzmaDec.obj \
|
$O\LzmaDec.obj \
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ C_OBJS = \
|
|||||||
$O\BraIA64.obj \
|
$O\BraIA64.obj \
|
||||||
$O\CpuArch.obj \
|
$O\CpuArch.obj \
|
||||||
$O\Delta.obj \
|
$O\Delta.obj \
|
||||||
|
$O\DllSecur.obj \
|
||||||
$O\Lzma2Dec.obj \
|
$O\Lzma2Dec.obj \
|
||||||
$O\LzmaDec.obj \
|
$O\LzmaDec.obj \
|
||||||
|
|
||||||
|
|||||||
18
C/Xz.c
18
C/Xz.c
@@ -1,5 +1,5 @@
|
|||||||
/* Xz.c - Xz
|
/* Xz.c - Xz
|
||||||
2015-05-01 : Igor Pavlov : Public domain */
|
2017-05-12 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
#include "XzCrc64.h"
|
#include "XzCrc64.h"
|
||||||
|
|
||||||
const Byte XZ_SIG[XZ_SIG_SIZE] = { 0xFD, '7', 'z', 'X', 'Z', 0 };
|
const Byte XZ_SIG[XZ_SIG_SIZE] = { 0xFD, '7', 'z', 'X', 'Z', 0 };
|
||||||
const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE] = { 'Y', 'Z' };
|
/* const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE] = { 'Y', 'Z' }; */
|
||||||
|
|
||||||
unsigned Xz_WriteVarInt(Byte *buf, UInt64 v)
|
unsigned Xz_WriteVarInt(Byte *buf, UInt64 v)
|
||||||
{
|
{
|
||||||
@@ -20,22 +20,22 @@ unsigned Xz_WriteVarInt(Byte *buf, UInt64 v)
|
|||||||
v >>= 7;
|
v >>= 7;
|
||||||
}
|
}
|
||||||
while (v != 0);
|
while (v != 0);
|
||||||
buf[i - 1] &= 0x7F;
|
buf[(size_t)i - 1] &= 0x7F;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Xz_Construct(CXzStream *p)
|
void Xz_Construct(CXzStream *p)
|
||||||
{
|
{
|
||||||
p->numBlocks = p->numBlocksAllocated = 0;
|
p->numBlocks = 0;
|
||||||
p->blocks = 0;
|
p->blocks = NULL;
|
||||||
p->flags = 0;
|
p->flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Xz_Free(CXzStream *p, ISzAlloc *alloc)
|
void Xz_Free(CXzStream *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->blocks);
|
ISzAlloc_Free(alloc, p->blocks);
|
||||||
p->numBlocks = p->numBlocksAllocated = 0;
|
p->numBlocks = 0;
|
||||||
p->blocks = 0;
|
p->blocks = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned XzFlags_GetCheckSize(CXzStreamFlags f)
|
unsigned XzFlags_GetCheckSize(CXzStreamFlags f)
|
||||||
|
|||||||
51
C/Xz.h
51
C/Xz.h
@@ -1,5 +1,5 @@
|
|||||||
/* Xz.h - Xz interface
|
/* Xz.h - Xz interface
|
||||||
2015-05-01 : Igor Pavlov : Public domain */
|
2017-07-27 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __XZ_H
|
#ifndef __XZ_H
|
||||||
#define __XZ_H
|
#define __XZ_H
|
||||||
@@ -50,6 +50,7 @@ typedef struct
|
|||||||
#define XzBlock_GetNumFilters(p) (((p)->flags & XZ_BF_NUM_FILTERS_MASK) + 1)
|
#define XzBlock_GetNumFilters(p) (((p)->flags & XZ_BF_NUM_FILTERS_MASK) + 1)
|
||||||
#define XzBlock_HasPackSize(p) (((p)->flags & XZ_BF_PACK_SIZE) != 0)
|
#define XzBlock_HasPackSize(p) (((p)->flags & XZ_BF_PACK_SIZE) != 0)
|
||||||
#define XzBlock_HasUnpackSize(p) (((p)->flags & XZ_BF_UNPACK_SIZE) != 0)
|
#define XzBlock_HasUnpackSize(p) (((p)->flags & XZ_BF_UNPACK_SIZE) != 0)
|
||||||
|
#define XzBlock_HasUnsupportedFlags(p) (((p)->flags & ~(XZ_BF_NUM_FILTERS_MASK | XZ_BF_PACK_SIZE | XZ_BF_UNPACK_SIZE)) != 0)
|
||||||
|
|
||||||
SRes XzBlock_Parse(CXzBlock *p, const Byte *header);
|
SRes XzBlock_Parse(CXzBlock *p, const Byte *header);
|
||||||
SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt32 *headerSizeRes);
|
SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt32 *headerSizeRes);
|
||||||
@@ -60,7 +61,13 @@ SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt
|
|||||||
#define XZ_FOOTER_SIG_SIZE 2
|
#define XZ_FOOTER_SIG_SIZE 2
|
||||||
|
|
||||||
extern const Byte XZ_SIG[XZ_SIG_SIZE];
|
extern const Byte XZ_SIG[XZ_SIG_SIZE];
|
||||||
|
|
||||||
|
/*
|
||||||
extern const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE];
|
extern const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE];
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define XZ_FOOTER_SIG_0 'Y'
|
||||||
|
#define XZ_FOOTER_SIG_1 'Z'
|
||||||
|
|
||||||
#define XZ_STREAM_FLAGS_SIZE 2
|
#define XZ_STREAM_FLAGS_SIZE 2
|
||||||
#define XZ_STREAM_CRC_SIZE 4
|
#define XZ_STREAM_CRC_SIZE 4
|
||||||
@@ -106,13 +113,12 @@ typedef struct
|
|||||||
{
|
{
|
||||||
CXzStreamFlags flags;
|
CXzStreamFlags flags;
|
||||||
size_t numBlocks;
|
size_t numBlocks;
|
||||||
size_t numBlocksAllocated;
|
|
||||||
CXzBlockSizes *blocks;
|
CXzBlockSizes *blocks;
|
||||||
UInt64 startOffset;
|
UInt64 startOffset;
|
||||||
} CXzStream;
|
} CXzStream;
|
||||||
|
|
||||||
void Xz_Construct(CXzStream *p);
|
void Xz_Construct(CXzStream *p);
|
||||||
void Xz_Free(CXzStream *p, ISzAlloc *alloc);
|
void Xz_Free(CXzStream *p, ISzAllocPtr alloc);
|
||||||
|
|
||||||
#define XZ_SIZE_OVERFLOW ((UInt64)(Int64)-1)
|
#define XZ_SIZE_OVERFLOW ((UInt64)(Int64)-1)
|
||||||
|
|
||||||
@@ -127,8 +133,8 @@ typedef struct
|
|||||||
} CXzs;
|
} CXzs;
|
||||||
|
|
||||||
void Xzs_Construct(CXzs *p);
|
void Xzs_Construct(CXzs *p);
|
||||||
void Xzs_Free(CXzs *p, ISzAlloc *alloc);
|
void Xzs_Free(CXzs *p, ISzAllocPtr alloc);
|
||||||
SRes Xzs_ReadBackward(CXzs *p, ILookInStream *inStream, Int64 *startOffset, ICompressProgress *progress, ISzAlloc *alloc);
|
SRes Xzs_ReadBackward(CXzs *p, ILookInStream *inStream, Int64 *startOffset, ICompressProgress *progress, ISzAllocPtr alloc);
|
||||||
|
|
||||||
UInt64 Xzs_GetNumBlocks(const CXzs *p);
|
UInt64 Xzs_GetNumBlocks(const CXzs *p);
|
||||||
UInt64 Xzs_GetUnpackSize(const CXzs *p);
|
UInt64 Xzs_GetUnpackSize(const CXzs *p);
|
||||||
@@ -150,8 +156,8 @@ typedef enum
|
|||||||
typedef struct _IStateCoder
|
typedef struct _IStateCoder
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
void (*Free)(void *p, ISzAlloc *alloc);
|
void (*Free)(void *p, ISzAllocPtr alloc);
|
||||||
SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAlloc *alloc);
|
SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAllocPtr alloc);
|
||||||
void (*Init)(void *p);
|
void (*Init)(void *p);
|
||||||
SRes (*Code)(void *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
SRes (*Code)(void *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished);
|
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished);
|
||||||
@@ -161,7 +167,7 @@ typedef struct _IStateCoder
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ISzAlloc *alloc;
|
ISzAllocPtr alloc;
|
||||||
Byte *buf;
|
Byte *buf;
|
||||||
unsigned numCoders;
|
unsigned numCoders;
|
||||||
int finished[MIXCODER_NUM_FILTERS_MAX - 1];
|
int finished[MIXCODER_NUM_FILTERS_MAX - 1];
|
||||||
@@ -171,7 +177,7 @@ typedef struct
|
|||||||
IStateCoder coders[MIXCODER_NUM_FILTERS_MAX];
|
IStateCoder coders[MIXCODER_NUM_FILTERS_MAX];
|
||||||
} CMixCoder;
|
} CMixCoder;
|
||||||
|
|
||||||
void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc);
|
void MixCoder_Construct(CMixCoder *p, ISzAllocPtr alloc);
|
||||||
void MixCoder_Free(CMixCoder *p);
|
void MixCoder_Free(CMixCoder *p);
|
||||||
void MixCoder_Init(CMixCoder *p);
|
void MixCoder_Init(CMixCoder *p);
|
||||||
SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId);
|
SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId);
|
||||||
@@ -218,11 +224,14 @@ typedef struct
|
|||||||
CXzBlock block;
|
CXzBlock block;
|
||||||
CXzCheck check;
|
CXzCheck check;
|
||||||
CSha256 sha;
|
CSha256 sha;
|
||||||
|
|
||||||
|
unsigned decodeOnlyOneBlock;
|
||||||
|
|
||||||
Byte shaDigest[SHA256_DIGEST_SIZE];
|
Byte shaDigest[SHA256_DIGEST_SIZE];
|
||||||
Byte buf[XZ_BLOCK_HEADER_SIZE_MAX];
|
Byte buf[XZ_BLOCK_HEADER_SIZE_MAX];
|
||||||
} CXzUnpacker;
|
} CXzUnpacker;
|
||||||
|
|
||||||
void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc);
|
void XzUnpacker_Construct(CXzUnpacker *p, ISzAllocPtr alloc);
|
||||||
void XzUnpacker_Init(CXzUnpacker *p);
|
void XzUnpacker_Init(CXzUnpacker *p);
|
||||||
void XzUnpacker_Free(CXzUnpacker *p);
|
void XzUnpacker_Free(CXzUnpacker *p);
|
||||||
|
|
||||||
@@ -258,7 +267,7 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
|||||||
const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode,
|
const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode,
|
||||||
ECoderStatus *status);
|
ECoderStatus *status);
|
||||||
|
|
||||||
Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p);
|
Bool XzUnpacker_IsStreamWasFinished(const CXzUnpacker *p);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Call XzUnpacker_GetExtraSize after XzUnpacker_Code function to detect real size of
|
Call XzUnpacker_GetExtraSize after XzUnpacker_Code function to detect real size of
|
||||||
@@ -268,7 +277,25 @@ XzUnpacker_Code() returns:
|
|||||||
res == SZ_ERROR_NO_ARCHIVE
|
res == SZ_ERROR_NO_ARCHIVE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
UInt64 XzUnpacker_GetExtraSize(CXzUnpacker *p);
|
UInt64 XzUnpacker_GetExtraSize(const CXzUnpacker *p);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
for random block decoding:
|
||||||
|
XzUnpacker_Init();
|
||||||
|
set CXzUnpacker::streamFlags
|
||||||
|
XzUnpacker_PrepareToRandomBlockDecoding()
|
||||||
|
loop
|
||||||
|
{
|
||||||
|
XzUnpacker_Code()
|
||||||
|
XzUnpacker_IsBlockFinished()
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void XzUnpacker_PrepareToRandomBlockDecoding(CXzUnpacker *p);
|
||||||
|
Bool XzUnpacker_IsBlockFinished(const CXzUnpacker *p);
|
||||||
|
|
||||||
|
#define XzUnpacker_GetPackSizeForIndex(p) ((p)->packSize + (p)->blockHeaderSize + XzFlags_GetCheckSize((p)->streamFlags))
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
|
|||||||
22
C/XzCrc64.c
22
C/XzCrc64.c
@@ -1,5 +1,5 @@
|
|||||||
/* XzCrc64.c -- CRC64 calculation
|
/* XzCrc64.c -- CRC64 calculation
|
||||||
2015-03-01 : Igor Pavlov : Public domain */
|
2017-05-23 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -9,9 +9,9 @@
|
|||||||
#define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42)
|
#define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42)
|
||||||
|
|
||||||
#ifdef MY_CPU_LE
|
#ifdef MY_CPU_LE
|
||||||
#define CRC_NUM_TABLES 4
|
#define CRC64_NUM_TABLES 4
|
||||||
#else
|
#else
|
||||||
#define CRC_NUM_TABLES 5
|
#define CRC64_NUM_TABLES 5
|
||||||
#define CRC_UINT64_SWAP(v) \
|
#define CRC_UINT64_SWAP(v) \
|
||||||
((v >> 56) \
|
((v >> 56) \
|
||||||
| ((v >> 40) & ((UInt64)0xFF << 8)) \
|
| ((v >> 40) & ((UInt64)0xFF << 8)) \
|
||||||
@@ -29,10 +29,10 @@
|
|||||||
UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table);
|
UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef UInt64 (MY_FAST_CALL *CRC_FUNC)(UInt64 v, const void *data, size_t size, const UInt64 *table);
|
typedef UInt64 (MY_FAST_CALL *CRC64_FUNC)(UInt64 v, const void *data, size_t size, const UInt64 *table);
|
||||||
|
|
||||||
static CRC_FUNC g_Crc64Update;
|
static CRC64_FUNC g_Crc64Update;
|
||||||
UInt64 g_Crc64Table[256 * CRC_NUM_TABLES];
|
UInt64 g_Crc64Table[256 * CRC64_NUM_TABLES];
|
||||||
|
|
||||||
UInt64 MY_FAST_CALL Crc64Update(UInt64 v, const void *data, size_t size)
|
UInt64 MY_FAST_CALL Crc64Update(UInt64 v, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
@@ -52,12 +52,12 @@ void MY_FAST_CALL Crc64GenerateTable()
|
|||||||
UInt64 r = i;
|
UInt64 r = i;
|
||||||
unsigned j;
|
unsigned j;
|
||||||
for (j = 0; j < 8; j++)
|
for (j = 0; j < 8; j++)
|
||||||
r = (r >> 1) ^ (kCrc64Poly & ~((r & 1) - 1));
|
r = (r >> 1) ^ (kCrc64Poly & ((UInt64)0 - (r & 1)));
|
||||||
g_Crc64Table[i] = r;
|
g_Crc64Table[i] = r;
|
||||||
}
|
}
|
||||||
for (; i < 256 * CRC_NUM_TABLES; i++)
|
for (i = 256; i < 256 * CRC64_NUM_TABLES; i++)
|
||||||
{
|
{
|
||||||
UInt64 r = g_Crc64Table[i - 256];
|
UInt64 r = g_Crc64Table[(size_t)i - 256];
|
||||||
g_Crc64Table[i] = g_Crc64Table[r & 0xFF] ^ (r >> 8);
|
g_Crc64Table[i] = g_Crc64Table[r & 0xFF] ^ (r >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,9 +74,9 @@ void MY_FAST_CALL Crc64GenerateTable()
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
|
for (i = 256 * CRC64_NUM_TABLES - 1; i >= 256; i--)
|
||||||
{
|
{
|
||||||
UInt64 x = g_Crc64Table[i - 256];
|
UInt64 x = g_Crc64Table[(size_t)i - 256];
|
||||||
g_Crc64Table[i] = CRC_UINT64_SWAP(x);
|
g_Crc64Table[i] = CRC_UINT64_SWAP(x);
|
||||||
}
|
}
|
||||||
g_Crc64Update = XzCrc64UpdateT1_BeT4;
|
g_Crc64Update = XzCrc64UpdateT1_BeT4;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* XzCrc64Opt.c -- CRC64 calculation
|
/* XzCrc64Opt.c -- CRC64 calculation
|
||||||
2015-03-01 : Igor Pavlov : Public domain */
|
2017-06-30 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -7,24 +7,24 @@
|
|||||||
|
|
||||||
#ifndef MY_CPU_BE
|
#ifndef MY_CPU_BE
|
||||||
|
|
||||||
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
#define CRC64_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||||
|
|
||||||
UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table)
|
UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table)
|
||||||
{
|
{
|
||||||
const Byte *p = (const Byte *)data;
|
const Byte *p = (const Byte *)data;
|
||||||
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
|
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
|
||||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
v = CRC64_UPDATE_BYTE_2(v, *p);
|
||||||
for (; size >= 4; size -= 4, p += 4)
|
for (; size >= 4; size -= 4, p += 4)
|
||||||
{
|
{
|
||||||
UInt32 d = (UInt32)v ^ *(const UInt32 *)p;
|
UInt32 d = (UInt32)v ^ *(const UInt32 *)p;
|
||||||
v = (v >> 32)
|
v = (v >> 32)
|
||||||
^ table[0x300 + ((d ) & 0xFF)]
|
^ (table + 0x300)[((d ) & 0xFF)]
|
||||||
^ table[0x200 + ((d >> 8) & 0xFF)]
|
^ (table + 0x200)[((d >> 8) & 0xFF)]
|
||||||
^ table[0x100 + ((d >> 16) & 0xFF)]
|
^ (table + 0x100)[((d >> 16) & 0xFF)]
|
||||||
^ table[0x000 + ((d >> 24))];
|
^ (table + 0x000)[((d >> 24))];
|
||||||
}
|
}
|
||||||
for (; size > 0; size--, p++)
|
for (; size > 0; size--, p++)
|
||||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
v = CRC64_UPDATE_BYTE_2(v, *p);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, con
|
|||||||
| ((v << 40) & ((UInt64)0xFF << 48)) \
|
| ((v << 40) & ((UInt64)0xFF << 48)) \
|
||||||
| ((v << 56)))
|
| ((v << 56)))
|
||||||
|
|
||||||
#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(Byte)((crc) >> 56) ^ (b)] ^ ((crc) << 8))
|
#define CRC64_UPDATE_BYTE_2_BE(crc, b) (table[(Byte)((crc) >> 56) ^ (b)] ^ ((crc) << 8))
|
||||||
|
|
||||||
UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table)
|
UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table)
|
||||||
{
|
{
|
||||||
@@ -51,18 +51,18 @@ UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size
|
|||||||
table += 0x100;
|
table += 0x100;
|
||||||
v = CRC_UINT64_SWAP(v);
|
v = CRC_UINT64_SWAP(v);
|
||||||
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
|
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
|
||||||
v = CRC_UPDATE_BYTE_2_BE(v, *p);
|
v = CRC64_UPDATE_BYTE_2_BE(v, *p);
|
||||||
for (; size >= 4; size -= 4, p += 4)
|
for (; size >= 4; size -= 4, p += 4)
|
||||||
{
|
{
|
||||||
UInt32 d = (UInt32)(v >> 32) ^ *(const UInt32 *)p;
|
UInt32 d = (UInt32)(v >> 32) ^ *(const UInt32 *)p;
|
||||||
v = (v << 32)
|
v = (v << 32)
|
||||||
^ table[0x000 + ((d ) & 0xFF)]
|
^ (table + 0x000)[((d ) & 0xFF)]
|
||||||
^ table[0x100 + ((d >> 8) & 0xFF)]
|
^ (table + 0x100)[((d >> 8) & 0xFF)]
|
||||||
^ table[0x200 + ((d >> 16) & 0xFF)]
|
^ (table + 0x200)[((d >> 16) & 0xFF)]
|
||||||
^ table[0x300 + ((d >> 24))];
|
^ (table + 0x300)[((d >> 24))];
|
||||||
}
|
}
|
||||||
for (; size > 0; size--, p++)
|
for (; size > 0; size--, p++)
|
||||||
v = CRC_UPDATE_BYTE_2_BE(v, *p);
|
v = CRC64_UPDATE_BYTE_2_BE(v, *p);
|
||||||
return CRC_UINT64_SWAP(v);
|
return CRC_UINT64_SWAP(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
206
C/XzDec.c
206
C/XzDec.c
@@ -1,5 +1,5 @@
|
|||||||
/* XzDec.c -- Xz Decode
|
/* XzDec.c -- Xz Decode
|
||||||
2015-11-09 : Igor Pavlov : Public domain */
|
2018-01-21 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
#define XZ_CHECK_SIZE_MAX 64
|
#define XZ_CHECK_SIZE_MAX 64
|
||||||
|
|
||||||
#define CODER_BUF_SIZE (1 << 17)
|
#define CODER_BUF_SIZE ((size_t)1 << 17)
|
||||||
|
|
||||||
unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value)
|
unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value)
|
||||||
{
|
{
|
||||||
@@ -66,12 +66,12 @@ typedef struct
|
|||||||
Byte buf[BRA_BUF_SIZE];
|
Byte buf[BRA_BUF_SIZE];
|
||||||
} CBraState;
|
} CBraState;
|
||||||
|
|
||||||
static void BraState_Free(void *pp, ISzAlloc *alloc)
|
static void BraState_Free(void *pp, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, pp);
|
ISzAlloc_Free(alloc, pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
|
static SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
CBraState *p = ((CBraState *)pp);
|
CBraState *p = ((CBraState *)pp);
|
||||||
UNUSED_VAR(alloc);
|
UNUSED_VAR(alloc);
|
||||||
@@ -197,7 +197,7 @@ static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc)
|
SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
CBraState *decoder;
|
CBraState *decoder;
|
||||||
if (id != XZ_ID_Delta &&
|
if (id != XZ_ID_Delta &&
|
||||||
@@ -209,8 +209,8 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc
|
|||||||
id != XZ_ID_SPARC)
|
id != XZ_ID_SPARC)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
p->p = 0;
|
p->p = 0;
|
||||||
decoder = (CBraState *)alloc->Alloc(alloc, sizeof(CBraState));
|
decoder = (CBraState *)ISzAlloc_Alloc(alloc, sizeof(CBraState));
|
||||||
if (decoder == 0)
|
if (!decoder)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
decoder->methodId = (UInt32)id;
|
decoder->methodId = (UInt32)id;
|
||||||
decoder->encodeMode = encodeMode;
|
decoder->encodeMode = encodeMode;
|
||||||
@@ -226,14 +226,14 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc
|
|||||||
|
|
||||||
#ifdef USE_SUBBLOCK
|
#ifdef USE_SUBBLOCK
|
||||||
|
|
||||||
static void SbState_Free(void *pp, ISzAlloc *alloc)
|
static void SbState_Free(void *pp, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
CSbDec *p = (CSbDec *)pp;
|
CSbDec *p = (CSbDec *)pp;
|
||||||
SbDec_Free(p);
|
SbDec_Free(p);
|
||||||
alloc->Free(alloc, pp);
|
ISzAlloc_Free(alloc, pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
|
static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
UNUSED_VAR(pp);
|
UNUSED_VAR(pp);
|
||||||
UNUSED_VAR(props);
|
UNUSED_VAR(props);
|
||||||
@@ -264,12 +264,12 @@ static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
|
SRes SbState_SetFromMethod(IStateCoder *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
CSbDec *decoder;
|
CSbDec *decoder;
|
||||||
p->p = 0;
|
p->p = 0;
|
||||||
decoder = alloc->Alloc(alloc, sizeof(CSbDec));
|
decoder = ISzAlloc_Alloc(alloc, sizeof(CSbDec));
|
||||||
if (decoder == 0)
|
if (!decoder)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
p->p = decoder;
|
p->p = decoder;
|
||||||
p->Free = SbState_Free;
|
p->Free = SbState_Free;
|
||||||
@@ -284,13 +284,13 @@ SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
|
|||||||
|
|
||||||
/* ---------- Lzma2State ---------- */
|
/* ---------- Lzma2State ---------- */
|
||||||
|
|
||||||
static void Lzma2State_Free(void *pp, ISzAlloc *alloc)
|
static void Lzma2State_Free(void *pp, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
Lzma2Dec_Free((CLzma2Dec *)pp, alloc);
|
Lzma2Dec_Free((CLzma2Dec *)pp, alloc);
|
||||||
alloc->Free(alloc, pp);
|
ISzAlloc_Free(alloc, pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes Lzma2State_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
|
static SRes Lzma2State_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
if (propSize != 1)
|
if (propSize != 1)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
@@ -313,11 +313,11 @@ static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *sr
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
|
static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
CLzma2Dec *decoder = (CLzma2Dec *)alloc->Alloc(alloc, sizeof(CLzma2Dec));
|
CLzma2Dec *decoder = (CLzma2Dec *)ISzAlloc_Alloc(alloc, sizeof(CLzma2Dec));
|
||||||
p->p = decoder;
|
p->p = decoder;
|
||||||
if (decoder == 0)
|
if (!decoder)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
p->Free = Lzma2State_Free;
|
p->Free = Lzma2State_Free;
|
||||||
p->SetProps = Lzma2State_SetProps;
|
p->SetProps = Lzma2State_SetProps;
|
||||||
@@ -328,7 +328,7 @@ static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc)
|
void MixCoder_Construct(CMixCoder *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
p->alloc = alloc;
|
p->alloc = alloc;
|
||||||
@@ -350,7 +350,7 @@ void MixCoder_Free(CMixCoder *p)
|
|||||||
p->numCoders = 0;
|
p->numCoders = 0;
|
||||||
if (p->buf)
|
if (p->buf)
|
||||||
{
|
{
|
||||||
p->alloc->Free(p->alloc, p->buf);
|
ISzAlloc_Free(p->alloc, p->buf);
|
||||||
p->buf = NULL; /* 9.31: the BUG was fixed */
|
p->buf = NULL; /* 9.31: the BUG was fixed */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -393,14 +393,14 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
|
|||||||
{
|
{
|
||||||
SizeT destLenOrig = *destLen;
|
SizeT destLenOrig = *destLen;
|
||||||
SizeT srcLenOrig = *srcLen;
|
SizeT srcLenOrig = *srcLen;
|
||||||
Bool allFinished = True;
|
|
||||||
*destLen = 0;
|
*destLen = 0;
|
||||||
*srcLen = 0;
|
*srcLen = 0;
|
||||||
*status = CODER_STATUS_NOT_FINISHED;
|
*status = CODER_STATUS_NOT_FINISHED;
|
||||||
|
|
||||||
if (!p->buf)
|
if (!p->buf)
|
||||||
{
|
{
|
||||||
p->buf = (Byte *)p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
|
p->buf = (Byte *)ISzAlloc_Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
|
||||||
if (!p->buf)
|
if (!p->buf)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
}
|
}
|
||||||
@@ -411,6 +411,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Bool processed = False;
|
Bool processed = False;
|
||||||
|
Bool allFinished = True;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
/*
|
/*
|
||||||
if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY)
|
if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY)
|
||||||
@@ -435,9 +436,10 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
srcCur = p->buf + (CODER_BUF_SIZE * (i - 1)) + p->pos[i - 1];
|
size_t k = i - 1;
|
||||||
srcLenCur = p->size[i - 1] - p->pos[i - 1];
|
srcCur = p->buf + (CODER_BUF_SIZE * k) + p->pos[k];
|
||||||
srcFinishedCur = p->finished[i - 1];
|
srcLenCur = p->size[k] - p->pos[k];
|
||||||
|
srcFinishedCur = p->finished[k];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == p->numCoders - 1)
|
if (i == p->numCoders - 1)
|
||||||
@@ -465,7 +467,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p->pos[i - 1] += srcLenCur;
|
p->pos[(size_t)i - 1] += srcLenCur;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == p->numCoders - 1)
|
if (i == p->numCoders - 1)
|
||||||
@@ -486,14 +488,17 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
|
|||||||
if (destLenCur != 0 || srcLenCur != 0)
|
if (destLenCur != 0 || srcLenCur != 0)
|
||||||
processed = True;
|
processed = True;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!processed)
|
if (!processed)
|
||||||
break;
|
{
|
||||||
|
if (allFinished)
|
||||||
|
*status = CODER_STATUS_FINISHED_WITH_MARK;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (allFinished)
|
|
||||||
*status = CODER_STATUS_FINISHED_WITH_MARK;
|
|
||||||
return SZ_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf)
|
SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf)
|
||||||
{
|
{
|
||||||
*p = (CXzStreamFlags)GetBe16(buf + XZ_SIG_SIZE);
|
*p = (CXzStreamFlags)GetBe16(buf + XZ_SIG_SIZE);
|
||||||
@@ -505,11 +510,11 @@ SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf)
|
|||||||
|
|
||||||
static Bool Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *buf)
|
static Bool Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *buf)
|
||||||
{
|
{
|
||||||
return
|
return indexSize == (((UInt64)GetUi32(buf + 4) + 1) << 2)
|
||||||
indexSize == (((UInt64)GetUi32(buf + 4) + 1) << 2) &&
|
&& GetUi32(buf) == CrcCalc(buf + 4, 6)
|
||||||
(GetUi32(buf) == CrcCalc(buf + 4, 6) &&
|
&& flags == GetBe16(buf + 8)
|
||||||
flags == GetBe16(buf + 8) &&
|
&& buf[10] == XZ_FOOTER_SIG_0
|
||||||
memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) == 0);
|
&& buf[11] == XZ_FOOTER_SIG_1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define READ_VARINT_AND_CHECK(buf, pos, size, res) \
|
#define READ_VARINT_AND_CHECK(buf, pos, size, res) \
|
||||||
@@ -523,14 +528,15 @@ SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
|
|||||||
unsigned numFilters, i;
|
unsigned numFilters, i;
|
||||||
unsigned headerSize = (unsigned)header[0] << 2;
|
unsigned headerSize = (unsigned)header[0] << 2;
|
||||||
|
|
||||||
|
/* (headerSize != 0) : another code checks */
|
||||||
|
|
||||||
if (CrcCalc(header, headerSize) != GetUi32(header + headerSize))
|
if (CrcCalc(header, headerSize) != GetUi32(header + headerSize))
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
|
||||||
pos = 1;
|
pos = 1;
|
||||||
if (pos == headerSize)
|
|
||||||
return SZ_ERROR_ARCHIVE;
|
|
||||||
p->flags = header[pos++];
|
p->flags = header[pos++];
|
||||||
|
|
||||||
|
p->packSize = (UInt64)(Int64)-1;
|
||||||
if (XzBlock_HasPackSize(p))
|
if (XzBlock_HasPackSize(p))
|
||||||
{
|
{
|
||||||
READ_VARINT_AND_CHECK(header, pos, headerSize, &p->packSize);
|
READ_VARINT_AND_CHECK(header, pos, headerSize, &p->packSize);
|
||||||
@@ -538,6 +544,7 @@ SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
|
|||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p->unpackSize = (UInt64)(Int64)-1;
|
||||||
if (XzBlock_HasUnpackSize(p))
|
if (XzBlock_HasUnpackSize(p))
|
||||||
READ_VARINT_AND_CHECK(header, pos, headerSize, &p->unpackSize);
|
READ_VARINT_AND_CHECK(header, pos, headerSize, &p->unpackSize);
|
||||||
|
|
||||||
@@ -564,6 +571,9 @@ SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (XzBlock_HasUnsupportedFlags(p))
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
|
||||||
while (pos < headerSize)
|
while (pos < headerSize)
|
||||||
if (header[pos++] != 0)
|
if (header[pos++] != 0)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
@@ -614,9 +624,10 @@ void XzUnpacker_Init(CXzUnpacker *p)
|
|||||||
p->numFinishedStreams = 0;
|
p->numFinishedStreams = 0;
|
||||||
p->numTotalBlocks = 0;
|
p->numTotalBlocks = 0;
|
||||||
p->padSize = 0;
|
p->padSize = 0;
|
||||||
|
p->decodeOnlyOneBlock = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc)
|
void XzUnpacker_Construct(CXzUnpacker *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
MixCoder_Construct(&p->decoder, alloc);
|
MixCoder_Construct(&p->decoder, alloc);
|
||||||
XzUnpacker_Init(p);
|
XzUnpacker_Init(p);
|
||||||
@@ -627,6 +638,18 @@ void XzUnpacker_Free(CXzUnpacker *p)
|
|||||||
MixCoder_Free(&p->decoder);
|
MixCoder_Free(&p->decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XzUnpacker_PrepareToRandomBlockDecoding(CXzUnpacker *p)
|
||||||
|
{
|
||||||
|
p->indexSize = 0;
|
||||||
|
p->numBlocks = 0;
|
||||||
|
Sha256_Init(&p->sha);
|
||||||
|
p->state = XZ_STATE_BLOCK_HEADER;
|
||||||
|
p->pos = 0;
|
||||||
|
p->decodeOnlyOneBlock = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
||||||
const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode, ECoderStatus *status)
|
const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode, ECoderStatus *status)
|
||||||
{
|
{
|
||||||
@@ -637,20 +660,44 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
|||||||
*status = CODER_STATUS_NOT_SPECIFIED;
|
*status = CODER_STATUS_NOT_SPECIFIED;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
SizeT srcRem = srcLenOrig - *srcLen;
|
SizeT srcRem;
|
||||||
|
|
||||||
if (p->state == XZ_STATE_BLOCK)
|
if (p->state == XZ_STATE_BLOCK)
|
||||||
{
|
{
|
||||||
SizeT destLen2 = destLenOrig - *destLen;
|
SizeT destLen2 = destLenOrig - *destLen;
|
||||||
SizeT srcLen2 = srcLenOrig - *srcLen;
|
SizeT srcLen2 = srcLenOrig - *srcLen;
|
||||||
SRes res;
|
SRes res;
|
||||||
|
|
||||||
|
ECoderFinishMode finishMode2 = finishMode;
|
||||||
|
|
||||||
|
if (p->block.packSize != (UInt64)(Int64)-1)
|
||||||
|
{
|
||||||
|
UInt64 rem = p->block.packSize - p->packSize;
|
||||||
|
if (srcLen2 > rem)
|
||||||
|
srcLen2 = (SizeT)rem;
|
||||||
|
if (rem == 0 && p->block.unpackSize == p->unpackSize)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->block.unpackSize != (UInt64)(Int64)-1)
|
||||||
|
{
|
||||||
|
UInt64 rem = p->block.unpackSize - p->unpackSize;
|
||||||
|
if (destLen2 >= rem)
|
||||||
|
{
|
||||||
|
finishMode2 = CODER_FINISH_END;
|
||||||
|
destLen2 = (SizeT)rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (srcLen2 == 0 && destLen2 == 0)
|
if (srcLen2 == 0 && destLen2 == 0)
|
||||||
{
|
{
|
||||||
*status = CODER_STATUS_NOT_FINISHED;
|
*status = CODER_STATUS_NOT_FINISHED;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
res = MixCoder_Code(&p->decoder, dest, &destLen2, src, &srcLen2, False, finishMode, status);
|
res = MixCoder_Code(&p->decoder, dest, &destLen2, src, &srcLen2, False, finishMode2, status);
|
||||||
XzCheck_Update(&p->check, dest, destLen2);
|
XzCheck_Update(&p->check, dest, destLen2);
|
||||||
|
|
||||||
(*srcLen) += srcLen2;
|
(*srcLen) += srcLen2;
|
||||||
@@ -660,29 +707,43 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
|||||||
(*destLen) += destLen2;
|
(*destLen) += destLen2;
|
||||||
dest += destLen2;
|
dest += destLen2;
|
||||||
p->unpackSize += destLen2;
|
p->unpackSize += destLen2;
|
||||||
|
|
||||||
RINOK(res);
|
RINOK(res);
|
||||||
|
|
||||||
if (*status == CODER_STATUS_FINISHED_WITH_MARK)
|
if (*status != CODER_STATUS_FINISHED_WITH_MARK)
|
||||||
|
{
|
||||||
|
if (p->block.packSize == p->packSize
|
||||||
|
&& *status == CODER_STATUS_NEEDS_MORE_INPUT)
|
||||||
|
{
|
||||||
|
*status = CODER_STATUS_NOT_SPECIFIED;
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (srcLen2 == 0 && destLen2 == 0)
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
{
|
{
|
||||||
Byte temp[32];
|
Byte temp[32];
|
||||||
unsigned num = Xz_WriteVarInt(temp, p->packSize + p->blockHeaderSize + XzFlags_GetCheckSize(p->streamFlags));
|
unsigned num = Xz_WriteVarInt(temp, XzUnpacker_GetPackSizeForIndex(p));
|
||||||
num += Xz_WriteVarInt(temp + num, p->unpackSize);
|
num += Xz_WriteVarInt(temp + num, p->unpackSize);
|
||||||
Sha256_Update(&p->sha, temp, num);
|
Sha256_Update(&p->sha, temp, num);
|
||||||
p->indexSize += num;
|
p->indexSize += num;
|
||||||
p->numBlocks++;
|
p->numBlocks++;
|
||||||
|
|
||||||
p->state = XZ_STATE_BLOCK_FOOTER;
|
p->state = XZ_STATE_BLOCK_FOOTER;
|
||||||
p->pos = 0;
|
p->pos = 0;
|
||||||
p->alignPos = 0;
|
p->alignPos = 0;
|
||||||
|
|
||||||
|
if (p->block.unpackSize != (UInt64)(Int64)-1)
|
||||||
|
if (p->block.unpackSize != p->unpackSize)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
}
|
}
|
||||||
else if (srcLen2 == 0 && destLen2 == 0)
|
// continue;
|
||||||
return SZ_OK;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srcRem == 0)
|
srcRem = srcLenOrig - *srcLen;
|
||||||
|
|
||||||
|
// XZ_STATE_BLOCK_FOOTER can transit to XZ_STATE_BLOCK_HEADER without input bytes
|
||||||
|
if (srcRem == 0 && p->state != XZ_STATE_BLOCK_FOOTER)
|
||||||
{
|
{
|
||||||
*status = CODER_STATUS_NEEDS_MORE_INPUT;
|
*status = CODER_STATUS_NEEDS_MORE_INPUT;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
@@ -703,10 +764,10 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
|||||||
{
|
{
|
||||||
RINOK(Xz_ParseHeader(&p->streamFlags, p->buf));
|
RINOK(Xz_ParseHeader(&p->streamFlags, p->buf));
|
||||||
p->numStartedStreams++;
|
p->numStartedStreams++;
|
||||||
p->state = XZ_STATE_BLOCK_HEADER;
|
|
||||||
Sha256_Init(&p->sha);
|
|
||||||
p->indexSize = 0;
|
p->indexSize = 0;
|
||||||
p->numBlocks = 0;
|
p->numBlocks = 0;
|
||||||
|
Sha256_Init(&p->sha);
|
||||||
|
p->state = XZ_STATE_BLOCK_HEADER;
|
||||||
p->pos = 0;
|
p->pos = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -720,6 +781,8 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
|||||||
(*srcLen)++;
|
(*srcLen)++;
|
||||||
if (p->buf[0] == 0)
|
if (p->buf[0] == 0)
|
||||||
{
|
{
|
||||||
|
if (p->decodeOnlyOneBlock)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
p->indexPreSize = 1 + Xz_WriteVarInt(p->buf + 1, p->numBlocks);
|
p->indexPreSize = 1 + Xz_WriteVarInt(p->buf + 1, p->numBlocks);
|
||||||
p->indexPos = p->indexPreSize;
|
p->indexPos = p->indexPreSize;
|
||||||
p->indexSize += p->indexPreSize;
|
p->indexSize += p->indexPreSize;
|
||||||
@@ -727,10 +790,13 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
|||||||
Sha256_Init(&p->sha);
|
Sha256_Init(&p->sha);
|
||||||
p->crc = CrcUpdate(CRC_INIT_VAL, p->buf, p->indexPreSize);
|
p->crc = CrcUpdate(CRC_INIT_VAL, p->buf, p->indexPreSize);
|
||||||
p->state = XZ_STATE_STREAM_INDEX;
|
p->state = XZ_STATE_STREAM_INDEX;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
p->blockHeaderSize = ((UInt32)p->buf[0] << 2) + 4;
|
p->blockHeaderSize = ((UInt32)p->buf[0] << 2) + 4;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (p->pos != p->blockHeaderSize)
|
|
||||||
|
if (p->pos != p->blockHeaderSize)
|
||||||
{
|
{
|
||||||
UInt32 cur = p->blockHeaderSize - p->pos;
|
UInt32 cur = p->blockHeaderSize - p->pos;
|
||||||
if (cur > srcRem)
|
if (cur > srcRem)
|
||||||
@@ -755,8 +821,13 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
|||||||
|
|
||||||
case XZ_STATE_BLOCK_FOOTER:
|
case XZ_STATE_BLOCK_FOOTER:
|
||||||
{
|
{
|
||||||
if (((p->packSize + p->alignPos) & 3) != 0)
|
if ((((unsigned)p->packSize + p->alignPos) & 3) != 0)
|
||||||
{
|
{
|
||||||
|
if (srcRem == 0)
|
||||||
|
{
|
||||||
|
*status = CODER_STATUS_NEEDS_MORE_INPUT;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
(*srcLen)++;
|
(*srcLen)++;
|
||||||
p->alignPos++;
|
p->alignPos++;
|
||||||
if (*src++ != 0)
|
if (*src++ != 0)
|
||||||
@@ -768,20 +839,31 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
|||||||
UInt32 cur = checkSize - p->pos;
|
UInt32 cur = checkSize - p->pos;
|
||||||
if (cur != 0)
|
if (cur != 0)
|
||||||
{
|
{
|
||||||
|
if (srcRem == 0)
|
||||||
|
{
|
||||||
|
*status = CODER_STATUS_NEEDS_MORE_INPUT;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
if (cur > srcRem)
|
if (cur > srcRem)
|
||||||
cur = (UInt32)srcRem;
|
cur = (UInt32)srcRem;
|
||||||
memcpy(p->buf + p->pos, src, cur);
|
memcpy(p->buf + p->pos, src, cur);
|
||||||
p->pos += cur;
|
p->pos += cur;
|
||||||
(*srcLen) += cur;
|
(*srcLen) += cur;
|
||||||
src += cur;
|
src += cur;
|
||||||
|
if (checkSize != p->pos)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
{
|
||||||
Byte digest[XZ_CHECK_SIZE_MAX];
|
Byte digest[XZ_CHECK_SIZE_MAX];
|
||||||
p->state = XZ_STATE_BLOCK_HEADER;
|
p->state = XZ_STATE_BLOCK_HEADER;
|
||||||
p->pos = 0;
|
p->pos = 0;
|
||||||
if (XzCheck_Final(&p->check, digest) && memcmp(digest, p->buf, checkSize) != 0)
|
if (XzCheck_Final(&p->check, digest) && memcmp(digest, p->buf, checkSize) != 0)
|
||||||
return SZ_ERROR_CRC;
|
return SZ_ERROR_CRC;
|
||||||
|
if (p->decodeOnlyOneBlock)
|
||||||
|
{
|
||||||
|
*status = CODER_STATUS_FINISHED_WITH_MARK;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -897,12 +979,18 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p)
|
|
||||||
|
Bool XzUnpacker_IsBlockFinished(const CXzUnpacker *p)
|
||||||
|
{
|
||||||
|
return (p->state == XZ_STATE_BLOCK_HEADER) && (p->pos == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool XzUnpacker_IsStreamWasFinished(const CXzUnpacker *p)
|
||||||
{
|
{
|
||||||
return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0);
|
return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt64 XzUnpacker_GetExtraSize(CXzUnpacker *p)
|
UInt64 XzUnpacker_GetExtraSize(const CXzUnpacker *p)
|
||||||
{
|
{
|
||||||
UInt64 num = 0;
|
UInt64 num = 0;
|
||||||
if (p->state == XZ_STATE_STREAM_PADDING)
|
if (p->state == XZ_STATE_STREAM_PADDING)
|
||||||
|
|||||||
27
C/XzEnc.h
27
C/XzEnc.h
@@ -1,5 +1,5 @@
|
|||||||
/* XzEnc.h -- Xz Encode
|
/* XzEnc.h -- Xz Encode
|
||||||
2011-02-07 : Igor Pavlov : Public domain */
|
2017-06-27 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __XZ_ENC_H
|
#ifndef __XZ_ENC_H
|
||||||
#define __XZ_ENC_H
|
#define __XZ_ENC_H
|
||||||
@@ -10,6 +10,11 @@
|
|||||||
|
|
||||||
EXTERN_C_BEGIN
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
|
||||||
|
#define XZ_PROPS__BLOCK_SIZE__AUTO LZMA2_ENC_PROPS__BLOCK_SIZE__AUTO
|
||||||
|
#define XZ_PROPS__BLOCK_SIZE__SOLID LZMA2_ENC_PROPS__BLOCK_SIZE__SOLID
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UInt32 id;
|
UInt32 id;
|
||||||
@@ -20,15 +25,31 @@ typedef struct
|
|||||||
|
|
||||||
void XzFilterProps_Init(CXzFilterProps *p);
|
void XzFilterProps_Init(CXzFilterProps *p);
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
const CLzma2EncProps *lzma2Props;
|
CLzma2EncProps lzma2Props;
|
||||||
const CXzFilterProps *filterProps;
|
CXzFilterProps filterProps;
|
||||||
unsigned checkId;
|
unsigned checkId;
|
||||||
|
UInt64 blockSize;
|
||||||
|
int numBlockThreads_Reduced;
|
||||||
|
int numBlockThreads_Max;
|
||||||
|
int numTotalThreads;
|
||||||
|
int forceWriteSizesInHeader;
|
||||||
|
UInt64 reduceSize;
|
||||||
} CXzProps;
|
} CXzProps;
|
||||||
|
|
||||||
void XzProps_Init(CXzProps *p);
|
void XzProps_Init(CXzProps *p);
|
||||||
|
|
||||||
|
|
||||||
|
typedef void * CXzEncHandle;
|
||||||
|
|
||||||
|
CXzEncHandle XzEnc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
||||||
|
void XzEnc_Destroy(CXzEncHandle p);
|
||||||
|
SRes XzEnc_SetProps(CXzEncHandle p, const CXzProps *props);
|
||||||
|
void XzEnc_SetDataSize(CXzEncHandle p, UInt64 expectedDataSiize);
|
||||||
|
SRes XzEnc_Encode(CXzEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress);
|
||||||
|
|
||||||
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
|
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||||
const CXzProps *props, ICompressProgress *progress);
|
const CXzProps *props, ICompressProgress *progress);
|
||||||
|
|
||||||
|
|||||||
60
C/XzIn.c
60
C/XzIn.c
@@ -1,5 +1,5 @@
|
|||||||
/* XzIn.c - Xz input
|
/* XzIn.c - Xz input
|
||||||
2015-11-08 : Igor Pavlov : Public domain */
|
2017-05-11 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -9,6 +9,12 @@
|
|||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
#include "Xz.h"
|
#include "Xz.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define XZ_FOOTER_SIG_CHECK(p) (memcmp((p), XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) == 0)
|
||||||
|
*/
|
||||||
|
#define XZ_FOOTER_SIG_CHECK(p) ((p)[0] == XZ_FOOTER_SIG_0 && (p)[1] == XZ_FOOTER_SIG_1)
|
||||||
|
|
||||||
|
|
||||||
SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream)
|
SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStream *inStream)
|
||||||
{
|
{
|
||||||
Byte sig[XZ_STREAM_HEADER_SIZE];
|
Byte sig[XZ_STREAM_HEADER_SIZE];
|
||||||
@@ -28,7 +34,7 @@ SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt
|
|||||||
unsigned headerSize;
|
unsigned headerSize;
|
||||||
*headerSizeRes = 0;
|
*headerSizeRes = 0;
|
||||||
RINOK(SeqInStream_ReadByte(inStream, &header[0]));
|
RINOK(SeqInStream_ReadByte(inStream, &header[0]));
|
||||||
headerSize = ((unsigned)header[0] << 2) + 4;
|
headerSize = (unsigned)header[0];
|
||||||
if (headerSize == 0)
|
if (headerSize == 0)
|
||||||
{
|
{
|
||||||
*headerSizeRes = 1;
|
*headerSizeRes = 1;
|
||||||
@@ -37,12 +43,13 @@ SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt
|
|||||||
}
|
}
|
||||||
|
|
||||||
*isIndex = False;
|
*isIndex = False;
|
||||||
|
headerSize = (headerSize << 2) + 4;
|
||||||
*headerSizeRes = headerSize;
|
*headerSizeRes = headerSize;
|
||||||
RINOK(SeqInStream_Read(inStream, header + 1, headerSize - 1));
|
RINOK(SeqInStream_Read(inStream, header + 1, headerSize - 1));
|
||||||
return XzBlock_Parse(p, header);
|
return XzBlock_Parse(p, header);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ADD_SIZE_CHECH(size, val) \
|
#define ADD_SIZE_CHECK(size, val) \
|
||||||
{ UInt64 newSize = size + (val); if (newSize < size) return XZ_SIZE_OVERFLOW; size = newSize; }
|
{ UInt64 newSize = size + (val); if (newSize < size) return XZ_SIZE_OVERFLOW; size = newSize; }
|
||||||
|
|
||||||
UInt64 Xz_GetUnpackSize(const CXzStream *p)
|
UInt64 Xz_GetUnpackSize(const CXzStream *p)
|
||||||
@@ -50,7 +57,7 @@ UInt64 Xz_GetUnpackSize(const CXzStream *p)
|
|||||||
UInt64 size = 0;
|
UInt64 size = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < p->numBlocks; i++)
|
for (i = 0; i < p->numBlocks; i++)
|
||||||
ADD_SIZE_CHECH(size, p->blocks[i].unpackSize);
|
ADD_SIZE_CHECK(size, p->blocks[i].unpackSize);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +66,7 @@ UInt64 Xz_GetPackSize(const CXzStream *p)
|
|||||||
UInt64 size = 0;
|
UInt64 size = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < p->numBlocks; i++)
|
for (i = 0; i < p->numBlocks; i++)
|
||||||
ADD_SIZE_CHECH(size, (p->blocks[i].totalSize + 3) & ~(UInt64)3);
|
ADD_SIZE_CHECK(size, (p->blocks[i].totalSize + 3) & ~(UInt64)3);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +77,7 @@ SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc)
|
static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
size_t numBlocks, pos = 1;
|
size_t numBlocks, pos = 1;
|
||||||
UInt32 crc;
|
UInt32 crc;
|
||||||
@@ -96,9 +103,8 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *
|
|||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
p->numBlocks = numBlocks;
|
p->numBlocks = numBlocks;
|
||||||
p->numBlocksAllocated = numBlocks;
|
p->blocks = ISzAlloc_Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks);
|
||||||
p->blocks = alloc->Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks);
|
if (!p->blocks)
|
||||||
if (p->blocks == 0)
|
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
for (i = 0; i < numBlocks; i++)
|
for (i = 0; i < numBlocks; i++)
|
||||||
{
|
{
|
||||||
@@ -115,7 +121,7 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *
|
|||||||
return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;
|
return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize, ISzAlloc *alloc)
|
static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
SRes res;
|
SRes res;
|
||||||
size_t size;
|
size_t size;
|
||||||
@@ -125,13 +131,13 @@ static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize,
|
|||||||
size = (size_t)indexSize;
|
size = (size_t)indexSize;
|
||||||
if (size != indexSize)
|
if (size != indexSize)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
buf = alloc->Alloc(alloc, size);
|
buf = ISzAlloc_Alloc(alloc, size);
|
||||||
if (buf == 0)
|
if (!buf)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
res = LookInStream_Read2(stream, buf, size, SZ_ERROR_UNSUPPORTED);
|
res = LookInStream_Read2(stream, buf, size, SZ_ERROR_UNSUPPORTED);
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
res = Xz_ReadIndex2(p, buf, size, alloc);
|
res = Xz_ReadIndex2(p, buf, size, alloc);
|
||||||
alloc->Free(alloc, buf);
|
ISzAlloc_Free(alloc, buf);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +148,7 @@ static SRes LookInStream_SeekRead_ForArc(ILookInStream *stream, UInt64 offset, v
|
|||||||
/* return LookInStream_Read2(stream, buf, size, SZ_ERROR_NO_ARCHIVE); */
|
/* return LookInStream_Read2(stream, buf, size, SZ_ERROR_NO_ARCHIVE); */
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAlloc *alloc)
|
static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
UInt64 indexSize;
|
UInt64 indexSize;
|
||||||
Byte buf[XZ_STREAM_FOOTER_SIZE];
|
Byte buf[XZ_STREAM_FOOTER_SIZE];
|
||||||
@@ -154,7 +160,7 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff
|
|||||||
pos -= XZ_STREAM_FOOTER_SIZE;
|
pos -= XZ_STREAM_FOOTER_SIZE;
|
||||||
RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE));
|
RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE));
|
||||||
|
|
||||||
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
|
if (!XZ_FOOTER_SIG_CHECK(buf + 10))
|
||||||
{
|
{
|
||||||
UInt32 total = 0;
|
UInt32 total = 0;
|
||||||
pos += XZ_STREAM_FOOTER_SIZE;
|
pos += XZ_STREAM_FOOTER_SIZE;
|
||||||
@@ -187,7 +193,7 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff
|
|||||||
return SZ_ERROR_NO_ARCHIVE;
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
pos -= XZ_STREAM_FOOTER_SIZE;
|
pos -= XZ_STREAM_FOOTER_SIZE;
|
||||||
RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE));
|
RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE));
|
||||||
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
|
if (!XZ_FOOTER_SIG_CHECK(buf + 10))
|
||||||
return SZ_ERROR_NO_ARCHIVE;
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +230,7 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff
|
|||||||
SecToRead_CreateVTable(&secToRead);
|
SecToRead_CreateVTable(&secToRead);
|
||||||
secToRead.realStream = stream;
|
secToRead.realStream = stream;
|
||||||
|
|
||||||
RINOK(Xz_ReadHeader(&headerFlags, &secToRead.s));
|
RINOK(Xz_ReadHeader(&headerFlags, &secToRead.vt));
|
||||||
return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE;
|
return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -238,12 +244,12 @@ void Xzs_Construct(CXzs *p)
|
|||||||
p->streams = 0;
|
p->streams = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Xzs_Free(CXzs *p, ISzAlloc *alloc)
|
void Xzs_Free(CXzs *p, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < p->num; i++)
|
for (i = 0; i < p->num; i++)
|
||||||
Xz_Free(&p->streams[i], alloc);
|
Xz_Free(&p->streams[i], alloc);
|
||||||
alloc->Free(alloc, p->streams);
|
ISzAlloc_Free(alloc, p->streams);
|
||||||
p->num = p->numAllocated = 0;
|
p->num = p->numAllocated = 0;
|
||||||
p->streams = 0;
|
p->streams = 0;
|
||||||
}
|
}
|
||||||
@@ -262,7 +268,7 @@ UInt64 Xzs_GetUnpackSize(const CXzs *p)
|
|||||||
UInt64 size = 0;
|
UInt64 size = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < p->num; i++)
|
for (i = 0; i < p->num; i++)
|
||||||
ADD_SIZE_CHECH(size, Xz_GetUnpackSize(&p->streams[i]));
|
ADD_SIZE_CHECK(size, Xz_GetUnpackSize(&p->streams[i]));
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,15 +278,15 @@ UInt64 Xzs_GetPackSize(const CXzs *p)
|
|||||||
UInt64 size = 0;
|
UInt64 size = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < p->num; i++)
|
for (i = 0; i < p->num; i++)
|
||||||
ADD_SIZE_CHECH(size, Xz_GetTotalSize(&p->streams[i]));
|
ADD_SIZE_CHECK(size, Xz_GetTotalSize(&p->streams[i]));
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompressProgress *progress, ISzAlloc *alloc)
|
SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompressProgress *progress, ISzAllocPtr alloc)
|
||||||
{
|
{
|
||||||
Int64 endOffset = 0;
|
Int64 endOffset = 0;
|
||||||
RINOK(stream->Seek(stream, &endOffset, SZ_SEEK_END));
|
RINOK(ILookInStream_Seek(stream, &endOffset, SZ_SEEK_END));
|
||||||
*startOffset = endOffset;
|
*startOffset = endOffset;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
@@ -293,20 +299,20 @@ SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompr
|
|||||||
if (p->num == p->numAllocated)
|
if (p->num == p->numAllocated)
|
||||||
{
|
{
|
||||||
size_t newNum = p->num + p->num / 4 + 1;
|
size_t newNum = p->num + p->num / 4 + 1;
|
||||||
Byte *data = (Byte *)alloc->Alloc(alloc, newNum * sizeof(CXzStream));
|
Byte *data = (Byte *)ISzAlloc_Alloc(alloc, newNum * sizeof(CXzStream));
|
||||||
if (data == 0)
|
if (!data)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
p->numAllocated = newNum;
|
p->numAllocated = newNum;
|
||||||
if (p->num != 0)
|
if (p->num != 0)
|
||||||
memcpy(data, p->streams, p->num * sizeof(CXzStream));
|
memcpy(data, p->streams, p->num * sizeof(CXzStream));
|
||||||
alloc->Free(alloc, p->streams);
|
ISzAlloc_Free(alloc, p->streams);
|
||||||
p->streams = (CXzStream *)data;
|
p->streams = (CXzStream *)data;
|
||||||
}
|
}
|
||||||
p->streams[p->num++] = st;
|
p->streams[p->num++] = st;
|
||||||
if (*startOffset == 0)
|
if (*startOffset == 0)
|
||||||
break;
|
break;
|
||||||
RINOK(LookInStream_SeekTo(stream, *startOffset));
|
RINOK(LookInStream_SeekTo(stream, *startOffset));
|
||||||
if (progress && progress->Progress(progress, endOffset - *startOffset, (UInt64)(Int64)-1) != SZ_OK)
|
if (progress && ICompressProgress_Progress(progress, endOffset - *startOffset, (UInt64)(Int64)-1) != SZ_OK)
|
||||||
return SZ_ERROR_PROGRESS;
|
return SZ_ERROR_PROGRESS;
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
C_OBJS = $(C_OBJS) \
|
C_OBJS = $(C_OBJS) \
|
||||||
$O\Aes.obj
|
$O\Aes.obj
|
||||||
|
|
||||||
!IF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS" && "$(CPU)" != "ARM"
|
!IF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS" && "$(CPU)" != "ARM" && "$(CPU)" != "ARM64"
|
||||||
ASM_OBJS = $(ASM_OBJS) \
|
ASM_OBJS = $(ASM_OBJS) \
|
||||||
$O\AesOpt.obj
|
$O\AesOpt.obj
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
|||||||
@@ -226,11 +226,13 @@ HRESULT CDecoder::Decode(
|
|||||||
|
|
||||||
, ISequentialOutStream *outStream
|
, ISequentialOutStream *outStream
|
||||||
, ICompressProgressInfo *compressProgress
|
, ICompressProgressInfo *compressProgress
|
||||||
|
|
||||||
, ISequentialInStream **
|
, ISequentialInStream **
|
||||||
|
#ifdef USE_MIXER_ST
|
||||||
|
inStreamMainRes
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_MIXER_ST
|
, bool &dataAfterEnd_Error
|
||||||
inStreamMainRes
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_7Z_DECODER_CRYPRO_VARS_DECL
|
_7Z_DECODER_CRYPRO_VARS_DECL
|
||||||
|
|
||||||
@@ -239,6 +241,8 @@ HRESULT CDecoder::Decode(
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
dataAfterEnd_Error = false;
|
||||||
|
|
||||||
const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]];
|
const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]];
|
||||||
CFolderEx folderInfo;
|
CFolderEx folderInfo;
|
||||||
folders.ParseFolderEx(folderIndex, folderInfo);
|
folders.ParseFolderEx(folderIndex, folderInfo);
|
||||||
@@ -404,23 +408,25 @@ HRESULT CDecoder::Decode(
|
|||||||
len = password.Len();
|
len = password.Len();
|
||||||
}
|
}
|
||||||
CByteBuffer buffer(len * 2);
|
CByteBuffer buffer(len * 2);
|
||||||
for (size_t i = 0; i < len; i++)
|
for (size_t k = 0; k < len; k++)
|
||||||
{
|
{
|
||||||
wchar_t c = passwordBSTR[i];
|
wchar_t c = passwordBSTR[k];
|
||||||
((Byte *)buffer)[i * 2] = (Byte)c;
|
((Byte *)buffer)[k * 2] = (Byte)c;
|
||||||
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
((Byte *)buffer)[k * 2 + 1] = (Byte)(c >> 8);
|
||||||
}
|
}
|
||||||
RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size()));
|
RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool finishMode = false;
|
||||||
{
|
{
|
||||||
CMyComPtr<ICompressSetFinishMode> setFinishMode;
|
CMyComPtr<ICompressSetFinishMode> setFinishMode;
|
||||||
decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode);
|
decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode);
|
||||||
if (setFinishMode)
|
if (setFinishMode)
|
||||||
{
|
{
|
||||||
RINOK(setFinishMode->SetFinishMode(BoolToInt(fullUnpack)));
|
finishMode = fullUnpack;
|
||||||
|
RINOK(setFinishMode->SetFinishMode(BoolToInt(finishMode)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,7 +456,7 @@ HRESULT CDecoder::Decode(
|
|||||||
unpackSize :
|
unpackSize :
|
||||||
&folders.CoderUnpackSizes[unpackStreamIndexStart + i];
|
&folders.CoderUnpackSizes[unpackStreamIndexStart + i];
|
||||||
|
|
||||||
_mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers);
|
_mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers, finishMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outStream)
|
if (outStream)
|
||||||
@@ -530,7 +536,9 @@ HRESULT CDecoder::Decode(
|
|||||||
progress2 = new CDecProgress(compressProgress);
|
progress2 = new CDecProgress(compressProgress);
|
||||||
|
|
||||||
ISequentialOutStream *outStreamPointer = outStream;
|
ISequentialOutStream *outStreamPointer = outStream;
|
||||||
return _mixer->Code(inStreamPointers, &outStreamPointer, progress2 ? (ICompressProgressInfo *)progress2 : compressProgress);
|
return _mixer->Code(inStreamPointers, &outStreamPointer,
|
||||||
|
progress2 ? (ICompressProgressInfo *)progress2 : compressProgress,
|
||||||
|
dataAfterEnd_Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_MIXER_ST
|
#ifdef USE_MIXER_ST
|
||||||
|
|||||||
@@ -53,7 +53,9 @@ public:
|
|||||||
|
|
||||||
, ISequentialOutStream *outStream
|
, ISequentialOutStream *outStream
|
||||||
, ICompressProgressInfo *compressProgress
|
, ICompressProgressInfo *compressProgress
|
||||||
|
|
||||||
, ISequentialInStream **inStreamMainRes
|
, ISequentialInStream **inStreamMainRes
|
||||||
|
, bool &dataAfterEnd_Error
|
||||||
|
|
||||||
_7Z_DECODER_CRYPRO_VARS_DECL
|
_7Z_DECODER_CRYPRO_VARS_DECL
|
||||||
|
|
||||||
|
|||||||
@@ -148,9 +148,9 @@ HRESULT CEncoder::CreateMixerCoder(
|
|||||||
|
|
||||||
RINOK(_mixer->SetBindInfo(_bindInfo));
|
RINOK(_mixer->SetBindInfo(_bindInfo));
|
||||||
|
|
||||||
FOR_VECTOR (i, _options.Methods)
|
FOR_VECTOR (m, _options.Methods)
|
||||||
{
|
{
|
||||||
const CMethodFull &methodFull = _options.Methods[i];
|
const CMethodFull &methodFull = _options.Methods[m];
|
||||||
|
|
||||||
CCreatedCoder cod;
|
CCreatedCoder cod;
|
||||||
|
|
||||||
@@ -333,7 +333,7 @@ HRESULT CEncoder::Encode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < numMethods; i++)
|
for (i = 0; i < numMethods; i++)
|
||||||
_mixer->SetCoderInfo(i, NULL, NULL);
|
_mixer->SetCoderInfo(i, NULL, NULL, false);
|
||||||
|
|
||||||
|
|
||||||
/* inStreamSize can be used by BCJ2 to set optimal range of conversion.
|
/* inStreamSize can be used by BCJ2 to set optimal range of conversion.
|
||||||
@@ -370,6 +370,17 @@ HRESULT CEncoder::Encode(
|
|||||||
resetInitVector->ResetInitVector();
|
resetInitVector->ResetInitVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
CMyComPtr<ICompressSetCoderPropertiesOpt> optProps;
|
||||||
|
coder->QueryInterface(IID_ICompressSetCoderPropertiesOpt, (void **)&optProps);
|
||||||
|
if (optProps)
|
||||||
|
{
|
||||||
|
PROPID propID = NCoderPropID::kExpectedDataSize;
|
||||||
|
NWindows::NCOM::CPropVariant prop = (UInt64)unpackSize;
|
||||||
|
RINOK(optProps->SetCoderPropertiesOpt(&propID, &prop, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
|
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
|
||||||
coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
|
coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
|
||||||
|
|
||||||
@@ -380,7 +391,7 @@ HRESULT CEncoder::Encode(
|
|||||||
CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;
|
CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;
|
||||||
CMyComPtr<ISequentialOutStream> dynOutStream(outStreamSpec);
|
CMyComPtr<ISequentialOutStream> dynOutStream(outStreamSpec);
|
||||||
outStreamSpec->Init();
|
outStreamSpec->Init();
|
||||||
writeCoderProperties->WriteCoderProperties(dynOutStream);
|
RINOK(writeCoderProperties->WriteCoderProperties(dynOutStream));
|
||||||
outStreamSpec->CopyToBuffer(props);
|
outStreamSpec->CopyToBuffer(props);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -410,9 +421,9 @@ HRESULT CEncoder::Encode(
|
|||||||
mtOutStreamNotifySpec->_stream = outStream;
|
mtOutStreamNotifySpec->_stream = outStream;
|
||||||
mtOutStreamNotifySpec->_mtProgresSpec = mtProgressSpec;
|
mtOutStreamNotifySpec->_mtProgresSpec = mtProgressSpec;
|
||||||
|
|
||||||
FOR_VECTOR(i, tempBufferSpecs)
|
FOR_VECTOR(t, tempBufferSpecs)
|
||||||
{
|
{
|
||||||
tempBufferSpecs[i]->_mtProgresSpec = mtProgressSpec;
|
tempBufferSpecs[t]->_mtProgresSpec = mtProgressSpec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,10 +440,12 @@ HRESULT CEncoder::Encode(
|
|||||||
for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
|
for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
|
||||||
outStreamPointers.Add(tempBuffers[i - 1]);
|
outStreamPointers.Add(tempBuffers[i - 1]);
|
||||||
|
|
||||||
|
bool dataAfterEnd_Error;
|
||||||
|
|
||||||
RINOK(_mixer->Code(
|
RINOK(_mixer->Code(
|
||||||
&inStreamPointer,
|
&inStreamPointer,
|
||||||
&outStreamPointers.Front(),
|
&outStreamPointers.Front(),
|
||||||
mtProgress ? (ICompressProgressInfo *)mtProgress : compressProgress));
|
mtProgress ? (ICompressProgressInfo *)mtProgress : compressProgress, dataAfterEnd_Error));
|
||||||
|
|
||||||
if (_bindInfo.PackStreams.Size() != 0)
|
if (_bindInfo.PackStreams.Size() != 0)
|
||||||
packSizes.Add(outStreamSizeCountSpec->GetSize());
|
packSizes.Add(outStreamSizeCountSpec->GetSize());
|
||||||
@@ -591,9 +604,9 @@ HRESULT CEncoder::EncoderConstr()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = _bindInfo.FindStream_in_PackStreams(outIndex);
|
int si = _bindInfo.FindStream_in_PackStreams(outIndex);
|
||||||
if (i >= 0)
|
if (si >= 0)
|
||||||
_bindInfo.PackStreams.MoveToFront(i);
|
_bindInfo.PackStreams.MoveToFront(si);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -319,13 +319,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
curUnpacked += _db.Files[k].Size;
|
curUnpacked += _db.Files[k].Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT result = folderOutStream->Init(fileIndex,
|
{
|
||||||
allFilesMode ? NULL : indices + i,
|
HRESULT result = folderOutStream->Init(fileIndex,
|
||||||
numSolidFiles);
|
allFilesMode ? NULL : indices + i,
|
||||||
|
numSolidFiles);
|
||||||
|
|
||||||
i += numSolidFiles;
|
i += numSolidFiles;
|
||||||
|
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
|
}
|
||||||
|
|
||||||
// to test solid block with zero unpacked size we disable that code
|
// to test solid block with zero unpacked size we disable that code
|
||||||
if (folderOutStream->WasWritingFinished())
|
if (folderOutStream->WasWritingFinished())
|
||||||
@@ -346,6 +348,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool dataAfterEnd_Error = false;
|
||||||
|
|
||||||
HRESULT result = decoder.Decode(
|
HRESULT result = decoder.Decode(
|
||||||
EXTERNAL_CODECS_VARS
|
EXTERNAL_CODECS_VARS
|
||||||
_inStream,
|
_inStream,
|
||||||
@@ -356,6 +360,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
outStream,
|
outStream,
|
||||||
progress,
|
progress,
|
||||||
NULL // *inStreamMainRes
|
NULL // *inStreamMainRes
|
||||||
|
, dataAfterEnd_Error
|
||||||
|
|
||||||
_7Z_DECODER_CRYPRO_VARS
|
_7Z_DECODER_CRYPRO_VARS
|
||||||
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
||||||
@@ -363,13 +368,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result == S_FALSE || result == E_NOTIMPL)
|
if (result == S_FALSE || result == E_NOTIMPL || dataAfterEnd_Error)
|
||||||
{
|
{
|
||||||
bool wasFinished = folderOutStream->WasWritingFinished();
|
bool wasFinished = folderOutStream->WasWritingFinished();
|
||||||
|
|
||||||
int resOp = (result == S_FALSE ?
|
int resOp = NExtract::NOperationResult::kDataError;
|
||||||
NExtract::NOperationResult::kDataError :
|
|
||||||
NExtract::NOperationResult::kUnsupportedMethod);
|
if (result != S_FALSE)
|
||||||
|
{
|
||||||
|
if (result == E_NOTIMPL)
|
||||||
|
resOp = NExtract::NOperationResult::kUnsupportedMethod;
|
||||||
|
else if (wasFinished && dataAfterEnd_Error)
|
||||||
|
resOp = NExtract::NOperationResult::kDataAfterEnd;
|
||||||
|
}
|
||||||
|
|
||||||
RINOK(folderOutStream->FlushCorrupted(resOp));
|
RINOK(folderOutStream->FlushCorrupted(resOp));
|
||||||
|
|
||||||
|
|||||||
@@ -80,14 +80,17 @@ STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
|
|||||||
{
|
{
|
||||||
if (_stream)
|
if (_stream)
|
||||||
{
|
{
|
||||||
UInt32 processed2;
|
UInt32 cur = size;
|
||||||
RINOK(_stream->Read(data, size, &processed2));
|
const UInt32 kMax = (UInt32)1 << 20;
|
||||||
if (processed2 != 0)
|
if (cur > kMax)
|
||||||
|
cur = kMax;
|
||||||
|
RINOK(_stream->Read(data, cur, &cur));
|
||||||
|
if (cur != 0)
|
||||||
{
|
{
|
||||||
_crc = CrcUpdate(_crc, data, processed2);
|
_crc = CrcUpdate(_crc, data, cur);
|
||||||
_pos += processed2;
|
_pos += cur;
|
||||||
if (processedSize)
|
if (processedSize)
|
||||||
*processedSize = processed2;
|
*processedSize = cur;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -429,11 +429,11 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
|
|||||||
name = "LZMA2";
|
name = "LZMA2";
|
||||||
if (propsSize == 1)
|
if (propsSize == 1)
|
||||||
{
|
{
|
||||||
Byte p = props[0];
|
Byte d = props[0];
|
||||||
if ((p & 1) == 0)
|
if ((d & 1) == 0)
|
||||||
ConvertUInt32ToString((UInt32)((p >> 1) + 12), s);
|
ConvertUInt32ToString((UInt32)((d >> 1) + 12), s);
|
||||||
else
|
else
|
||||||
GetStringForSizeValue(s, 3 << ((p >> 1) + 11));
|
GetStringForSizeValue(s, 3 << ((d >> 1) + 11));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (id == k_PPMD)
|
else if (id == k_PPMD)
|
||||||
@@ -540,7 +540,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const CFileItem &item = _db.Files[index];
|
const CFileItem &item = _db.Files[index];
|
||||||
UInt32 index2 = index;
|
const UInt32 index2 = index;
|
||||||
|
|
||||||
switch (propID)
|
switch (propID)
|
||||||
{
|
{
|
||||||
@@ -575,7 +575,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
case kpidCTime: SetFileTimeProp_From_UInt64Def(value, _db.CTime, index2); break;
|
case kpidCTime: SetFileTimeProp_From_UInt64Def(value, _db.CTime, index2); break;
|
||||||
case kpidATime: SetFileTimeProp_From_UInt64Def(value, _db.ATime, index2); break;
|
case kpidATime: SetFileTimeProp_From_UInt64Def(value, _db.ATime, index2); break;
|
||||||
case kpidMTime: SetFileTimeProp_From_UInt64Def(value, _db.MTime, index2); break;
|
case kpidMTime: SetFileTimeProp_From_UInt64Def(value, _db.MTime, index2); break;
|
||||||
case kpidAttrib: if (item.AttribDefined) PropVarEm_Set_UInt32(value, item.Attrib); break;
|
case kpidAttrib: if (_db.Attrib.ValidAndDefined(index2)) PropVarEm_Set_UInt32(value, _db.Attrib.Vals[index2]); break;
|
||||||
case kpidCRC: if (item.CrcDefined) PropVarEm_Set_UInt32(value, item.Crc); break;
|
case kpidCRC: if (item.CrcDefined) PropVarEm_Set_UInt32(value, item.Crc); break;
|
||||||
case kpidEncrypted: PropVarEm_Set_Bool(value, IsFolderEncrypted(_db.FileIndexToFolderIndexMap[index2])); break;
|
case kpidEncrypted: PropVarEm_Set_Bool(value, IsFolderEncrypted(_db.FileIndexToFolderIndexMap[index2])); break;
|
||||||
case kpidIsAnti: PropVarEm_Set_Bool(value, _db.IsItemAnti(index2)); break;
|
case kpidIsAnti: PropVarEm_Set_Bool(value, _db.IsItemAnti(index2)); break;
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public:
|
|||||||
CBoolPair Write_CTime;
|
CBoolPair Write_CTime;
|
||||||
CBoolPair Write_ATime;
|
CBoolPair Write_ATime;
|
||||||
CBoolPair Write_MTime;
|
CBoolPair Write_MTime;
|
||||||
|
CBoolPair Write_Attrib;
|
||||||
|
|
||||||
bool _useMultiThreadMixer;
|
bool _useMultiThreadMixer;
|
||||||
|
|
||||||
|
|||||||
@@ -18,11 +18,12 @@ using namespace NWindows;
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
static const char *k_LZMA_Name = "LZMA";
|
#define k_LZMA_Name "LZMA"
|
||||||
static const char *kDefaultMethodName = "LZMA2";
|
#define kDefaultMethodName "LZMA2"
|
||||||
static const char *k_Copy_Name = "Copy";
|
#define k_Copy_Name "Copy"
|
||||||
|
|
||||||
|
#define k_MatchFinder_ForHeaders "BT2"
|
||||||
|
|
||||||
static const char *k_MatchFinder_ForHeaders = "BT2";
|
|
||||||
static const UInt32 k_NumFastBytes_ForHeaders = 273;
|
static const UInt32 k_NumFastBytes_ForHeaders = 273;
|
||||||
static const UInt32 k_Level_ForHeaders = 5;
|
static const UInt32 k_Level_ForHeaders = 5;
|
||||||
static const UInt32 k_Dictionary_ForHeaders =
|
static const UInt32 k_Dictionary_ForHeaders =
|
||||||
@@ -113,11 +114,11 @@ HRESULT CHandler::SetMainMethod(
|
|||||||
FOR_VECTOR (i, methods)
|
FOR_VECTOR (i, methods)
|
||||||
{
|
{
|
||||||
COneMethodInfo &oneMethodInfo = methods[i];
|
COneMethodInfo &oneMethodInfo = methods[i];
|
||||||
SetGlobalLevelAndThreads(oneMethodInfo
|
|
||||||
#ifndef _7ZIP_ST
|
SetGlobalLevelTo(oneMethodInfo);
|
||||||
, numThreads
|
#ifndef _7ZIP_ST
|
||||||
#endif
|
CMultiMethodProps::SetMethodThreadsTo(oneMethodInfo, numThreads);
|
||||||
);
|
#endif
|
||||||
|
|
||||||
CMethodFull &methodFull = methodMode.Methods.AddNew();
|
CMethodFull &methodFull = methodMode.Methods.AddNew();
|
||||||
RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
|
RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
|
||||||
@@ -282,15 +283,18 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
bool need_CTime = (Write_CTime.Def && Write_CTime.Val);
|
bool need_CTime = (Write_CTime.Def && Write_CTime.Val);
|
||||||
bool need_ATime = (Write_ATime.Def && Write_ATime.Val);
|
bool need_ATime = (Write_ATime.Def && Write_ATime.Val);
|
||||||
bool need_MTime = (Write_MTime.Def && Write_MTime.Val || !Write_MTime.Def);
|
bool need_MTime = (Write_MTime.Def && Write_MTime.Val || !Write_MTime.Def);
|
||||||
|
bool need_Attrib = (Write_Attrib.Def && Write_Attrib.Val || !Write_Attrib.Def);
|
||||||
|
|
||||||
if (db && !db->Files.IsEmpty())
|
if (db && !db->Files.IsEmpty())
|
||||||
{
|
{
|
||||||
if (!Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty();
|
if (!Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty();
|
||||||
if (!Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty();
|
if (!Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty();
|
||||||
if (!Write_MTime.Def) need_MTime = !db->MTime.Defs.IsEmpty();
|
if (!Write_MTime.Def) need_MTime = !db->MTime.Defs.IsEmpty();
|
||||||
|
if (!Write_Attrib.Def) need_Attrib = !db->Attrib.Defs.IsEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
UString s;
|
// UString s;
|
||||||
|
UString name;
|
||||||
|
|
||||||
for (UInt32 i = 0; i < numItems; i++)
|
for (UInt32 i = 0; i < numItems; i++)
|
||||||
{
|
{
|
||||||
@@ -307,7 +311,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
ui.IsAnti = false;
|
ui.IsAnti = false;
|
||||||
ui.Size = 0;
|
ui.Size = 0;
|
||||||
|
|
||||||
UString name;
|
name.Empty();
|
||||||
// bool isAltStream = false;
|
// bool isAltStream = false;
|
||||||
if (ui.IndexInArchive != -1)
|
if (ui.IndexInArchive != -1)
|
||||||
{
|
{
|
||||||
@@ -334,6 +338,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
if (ui.NewProps)
|
if (ui.NewProps)
|
||||||
{
|
{
|
||||||
bool folderStatusIsDefined;
|
bool folderStatusIsDefined;
|
||||||
|
if (need_Attrib)
|
||||||
{
|
{
|
||||||
NCOM::CPropVariant prop;
|
NCOM::CPropVariant prop;
|
||||||
RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop));
|
RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop));
|
||||||
@@ -377,7 +382,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
name = NItemName::MakeLegalName(prop.bstrVal);
|
name = prop.bstrVal;
|
||||||
|
NItemName::ReplaceSlashes_OsToUnix(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@@ -614,6 +620,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
options.HeaderOptions.WriteCTime = Write_CTime;
|
options.HeaderOptions.WriteCTime = Write_CTime;
|
||||||
options.HeaderOptions.WriteATime = Write_ATime;
|
options.HeaderOptions.WriteATime = Write_ATime;
|
||||||
options.HeaderOptions.WriteMTime = Write_MTime;
|
options.HeaderOptions.WriteMTime = Write_MTime;
|
||||||
|
options.HeaderOptions.WriteAttrib = Write_Attrib;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
options.NumSolidFiles = _numSolidFiles;
|
options.NumSolidFiles = _numSolidFiles;
|
||||||
@@ -675,14 +682,16 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream)
|
static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream)
|
||||||
{
|
{
|
||||||
stream = 0;
|
stream = 0;
|
||||||
int index = ParseStringToUInt32(srcString, coder);
|
{
|
||||||
if (index == 0)
|
unsigned index = ParseStringToUInt32(srcString, coder);
|
||||||
return E_INVALIDARG;
|
if (index == 0)
|
||||||
srcString.DeleteFrontal(index);
|
return E_INVALIDARG;
|
||||||
|
srcString.DeleteFrontal(index);
|
||||||
|
}
|
||||||
if (srcString[0] == 's')
|
if (srcString[0] == 's')
|
||||||
{
|
{
|
||||||
srcString.Delete(0);
|
srcString.Delete(0);
|
||||||
int index = ParseStringToUInt32(srcString, stream);
|
unsigned index = ParseStringToUInt32(srcString, stream);
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
srcString.DeleteFrontal(index);
|
srcString.DeleteFrontal(index);
|
||||||
@@ -703,6 +712,7 @@ void COutHandler::InitProps()
|
|||||||
Write_CTime.Init();
|
Write_CTime.Init();
|
||||||
Write_ATime.Init();
|
Write_ATime.Init();
|
||||||
Write_MTime.Init();
|
Write_MTime.Init();
|
||||||
|
Write_Attrib.Init();
|
||||||
|
|
||||||
_useMultiThreadMixer = true;
|
_useMultiThreadMixer = true;
|
||||||
|
|
||||||
@@ -828,6 +838,8 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
|
|||||||
if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime);
|
if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime);
|
||||||
if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime);
|
if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime);
|
||||||
|
|
||||||
|
if (name.IsEqualTo("tr")) return PROPVARIANT_to_BoolPair(value, Write_Attrib);
|
||||||
|
|
||||||
if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer);
|
if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer);
|
||||||
|
|
||||||
if (name.IsEqualTo("qs")) return PROPVARIANT_to_bool(value, _useTypeSorting);
|
if (name.IsEqualTo("qs")) return PROPVARIANT_to_bool(value, _useTypeSorting);
|
||||||
|
|||||||
@@ -32,6 +32,21 @@ using namespace NCOM;
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
|
unsigned BoolVector_CountSum(const CBoolVector &v)
|
||||||
|
{
|
||||||
|
unsigned sum = 0;
|
||||||
|
const unsigned size = v.Size();
|
||||||
|
for (unsigned i = 0; i < size; i++)
|
||||||
|
if (v[i])
|
||||||
|
sum++;
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool BoolVector_Item_IsValidAndTrue(const CBoolVector &v, unsigned i)
|
||||||
|
{
|
||||||
|
return (i < v.Size() ? v[i] : false);
|
||||||
|
}
|
||||||
|
|
||||||
static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
|
static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
|
||||||
{
|
{
|
||||||
v.ClearAndSetSize(size);
|
v.ClearAndSetSize(size);
|
||||||
@@ -40,6 +55,7 @@ static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
|
|||||||
p[i] = false;
|
p[i] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class CInArchiveException {};
|
class CInArchiveException {};
|
||||||
class CUnsupportedFeatureException: public CInArchiveException {};
|
class CUnsupportedFeatureException: public CInArchiveException {};
|
||||||
|
|
||||||
@@ -566,21 +582,30 @@ void CInArchive::WaitId(UInt64 id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CInArchive::Read_UInt32_Vector(CUInt32DefVector &v)
|
||||||
|
{
|
||||||
|
unsigned numItems = v.Defs.Size();
|
||||||
|
v.Vals.ClearAndSetSize(numItems);
|
||||||
|
UInt32 *p = &v.Vals[0];
|
||||||
|
const bool *defs = &v.Defs[0];
|
||||||
|
for (unsigned i = 0; i < numItems; i++)
|
||||||
|
{
|
||||||
|
UInt32 a = 0;
|
||||||
|
if (defs[i])
|
||||||
|
a = ReadUInt32();
|
||||||
|
p[i] = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs)
|
void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs)
|
||||||
{
|
{
|
||||||
ReadBoolVector2(numItems, crcs.Defs);
|
ReadBoolVector2(numItems, crcs.Defs);
|
||||||
crcs.Vals.ClearAndSetSize(numItems);
|
Read_UInt32_Vector(crcs);
|
||||||
UInt32 *p = &crcs.Vals[0];
|
|
||||||
const bool *defs = &crcs.Defs[0];
|
|
||||||
for (unsigned i = 0; i < numItems; i++)
|
|
||||||
{
|
|
||||||
UInt32 crc = 0;
|
|
||||||
if (defs[i])
|
|
||||||
crc = ReadUInt32();
|
|
||||||
p[i] = crc;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define k_Scan_NumCoders_MAX 64
|
#define k_Scan_NumCoders_MAX 64
|
||||||
#define k_Scan_NumCodersStreams_in_Folder_MAX 64
|
#define k_Scan_NumCodersStreams_in_Folder_MAX 64
|
||||||
|
|
||||||
@@ -1075,6 +1100,8 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
|||||||
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
|
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
|
||||||
outStreamSpec->Init(data, unpackSize);
|
outStreamSpec->Init(data, unpackSize);
|
||||||
|
|
||||||
|
bool dataAfterEnd_Error = false;
|
||||||
|
|
||||||
HRESULT result = decoder.Decode(
|
HRESULT result = decoder.Decode(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
_stream, baseOffset + dataOffset,
|
_stream, baseOffset + dataOffset,
|
||||||
@@ -1083,21 +1110,31 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
|||||||
|
|
||||||
outStream,
|
outStream,
|
||||||
NULL, // *compressProgress
|
NULL, // *compressProgress
|
||||||
|
|
||||||
NULL // **inStreamMainRes
|
NULL // **inStreamMainRes
|
||||||
|
, dataAfterEnd_Error
|
||||||
|
|
||||||
_7Z_DECODER_CRYPRO_VARS
|
_7Z_DECODER_CRYPRO_VARS
|
||||||
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
||||||
, false // mtMode
|
, false // mtMode
|
||||||
, 1 // numThreads
|
, 1 // numThreads
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
|
|
||||||
|
if (dataAfterEnd_Error)
|
||||||
|
ThereIsHeaderError = true;
|
||||||
|
|
||||||
if (folders.FolderCRCs.ValidAndDefined(i))
|
if (folders.FolderCRCs.ValidAndDefined(i))
|
||||||
if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i])
|
if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i])
|
||||||
ThrowIncorrect();
|
ThrowIncorrect();
|
||||||
}
|
}
|
||||||
HeadersSize += folders.PackPositions[folders.NumPackStreams];
|
|
||||||
|
if (folders.PackPositions)
|
||||||
|
HeadersSize += folders.PackPositions[folders.NumPackStreams];
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1145,20 +1182,10 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
type = ReadID();
|
type = ReadID();
|
||||||
}
|
}
|
||||||
|
|
||||||
db.Files.Clear();
|
|
||||||
|
|
||||||
if (type == NID::kFilesInfo)
|
if (type == NID::kFilesInfo)
|
||||||
{
|
{
|
||||||
|
|
||||||
CNum numFiles = ReadNum();
|
const CNum numFiles = ReadNum();
|
||||||
db.Files.ClearAndSetSize(numFiles);
|
|
||||||
CNum i;
|
|
||||||
/*
|
|
||||||
db.Files.Reserve(numFiles);
|
|
||||||
CNum i;
|
|
||||||
for (i = 0; i < numFiles; i++)
|
|
||||||
db.Files.Add(CFileItem());
|
|
||||||
*/
|
|
||||||
|
|
||||||
db.ArcInfo.FileInfoPopIDs.Add(NID::kSize);
|
db.ArcInfo.FileInfoPopIDs.Add(NID::kSize);
|
||||||
// if (!db.PackSizes.IsEmpty())
|
// if (!db.PackSizes.IsEmpty())
|
||||||
@@ -1167,15 +1194,14 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
db.ArcInfo.FileInfoPopIDs.Add(NID::kCRC);
|
db.ArcInfo.FileInfoPopIDs.Add(NID::kCRC);
|
||||||
|
|
||||||
CBoolVector emptyStreamVector;
|
CBoolVector emptyStreamVector;
|
||||||
BoolVector_Fill_False(emptyStreamVector, (unsigned)numFiles);
|
|
||||||
CBoolVector emptyFileVector;
|
CBoolVector emptyFileVector;
|
||||||
CBoolVector antiFileVector;
|
CBoolVector antiFileVector;
|
||||||
CNum numEmptyStreams = 0;
|
CNum numEmptyStreams = 0;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
UInt64 type = ReadID();
|
const UInt64 type2 = ReadID();
|
||||||
if (type == NID::kEnd)
|
if (type2 == NID::kEnd)
|
||||||
break;
|
break;
|
||||||
UInt64 size = ReadNumber();
|
UInt64 size = ReadNumber();
|
||||||
if (size > _inByteBack->GetRem())
|
if (size > _inByteBack->GetRem())
|
||||||
@@ -1184,9 +1210,9 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
switchProp.Set(this, _inByteBack->GetPtr(), (size_t)size, true);
|
switchProp.Set(this, _inByteBack->GetPtr(), (size_t)size, true);
|
||||||
bool addPropIdToList = true;
|
bool addPropIdToList = true;
|
||||||
bool isKnownType = true;
|
bool isKnownType = true;
|
||||||
if (type > ((UInt32)1 << 30))
|
if (type2 > ((UInt32)1 << 30))
|
||||||
isKnownType = false;
|
isKnownType = false;
|
||||||
else switch ((UInt32)type)
|
else switch ((UInt32)type2)
|
||||||
{
|
{
|
||||||
case NID::kName:
|
case NID::kName:
|
||||||
{
|
{
|
||||||
@@ -1195,10 +1221,10 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
size_t rem = _inByteBack->GetRem();
|
size_t rem = _inByteBack->GetRem();
|
||||||
db.NamesBuf.Alloc(rem);
|
db.NamesBuf.Alloc(rem);
|
||||||
ReadBytes(db.NamesBuf, rem);
|
ReadBytes(db.NamesBuf, rem);
|
||||||
db.NameOffsets.Alloc(db.Files.Size() + 1);
|
db.NameOffsets.Alloc(numFiles + 1);
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i < db.Files.Size(); i++)
|
for (i = 0; i < numFiles; i++)
|
||||||
{
|
{
|
||||||
size_t curRem = (rem - pos) / 2;
|
size_t curRem = (rem - pos) / 2;
|
||||||
const UInt16 *buf = (const UInt16 *)(db.NamesBuf + pos);
|
const UInt16 *buf = (const UInt16 *)(db.NamesBuf + pos);
|
||||||
@@ -1214,36 +1240,31 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
ThereIsHeaderError = true;
|
ThereIsHeaderError = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NID::kWinAttrib:
|
case NID::kWinAttrib:
|
||||||
{
|
{
|
||||||
CBoolVector boolVector;
|
ReadBoolVector2(numFiles, db.Attrib.Defs);
|
||||||
ReadBoolVector2(db.Files.Size(), boolVector);
|
|
||||||
CStreamSwitch streamSwitch;
|
CStreamSwitch streamSwitch;
|
||||||
streamSwitch.Set(this, &dataVector);
|
streamSwitch.Set(this, &dataVector);
|
||||||
for (i = 0; i < numFiles; i++)
|
Read_UInt32_Vector(db.Attrib);
|
||||||
{
|
|
||||||
CFileItem &file = db.Files[i];
|
|
||||||
file.AttribDefined = boolVector[i];
|
|
||||||
if (file.AttribDefined)
|
|
||||||
file.Attrib = ReadUInt32();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
case NID::kIsAux:
|
case NID::kIsAux:
|
||||||
{
|
{
|
||||||
ReadBoolVector(db.Files.Size(), db.IsAux);
|
ReadBoolVector(numFiles, db.IsAux);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NID::kParent:
|
case NID::kParent:
|
||||||
{
|
{
|
||||||
db.IsTree = true;
|
db.IsTree = true;
|
||||||
// CBoolVector boolVector;
|
// CBoolVector boolVector;
|
||||||
// ReadBoolVector2(db.Files.Size(), boolVector);
|
// ReadBoolVector2(numFiles, boolVector);
|
||||||
// CStreamSwitch streamSwitch;
|
// CStreamSwitch streamSwitch;
|
||||||
// streamSwitch.Set(this, &dataVector);
|
// streamSwitch.Set(this, &dataVector);
|
||||||
CBoolVector boolVector;
|
CBoolVector boolVector;
|
||||||
ReadBoolVector2(db.Files.Size(), boolVector);
|
ReadBoolVector2(numFiles, boolVector);
|
||||||
|
|
||||||
db.ThereAreAltStreams = false;
|
db.ThereAreAltStreams = false;
|
||||||
for (i = 0; i < numFiles; i++)
|
for (i = 0; i < numFiles; i++)
|
||||||
@@ -1262,14 +1283,9 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
case NID::kEmptyStream:
|
case NID::kEmptyStream:
|
||||||
{
|
{
|
||||||
ReadBoolVector(numFiles, emptyStreamVector);
|
ReadBoolVector(numFiles, emptyStreamVector);
|
||||||
numEmptyStreams = 0;
|
numEmptyStreams = BoolVector_CountSum(emptyStreamVector);
|
||||||
for (i = 0; i < (CNum)emptyStreamVector.Size(); i++)
|
emptyFileVector.Clear();
|
||||||
if (emptyStreamVector[i])
|
antiFileVector.Clear();
|
||||||
numEmptyStreams++;
|
|
||||||
|
|
||||||
BoolVector_Fill_False(emptyFileVector, numEmptyStreams);
|
|
||||||
BoolVector_Fill_False(antiFileVector, numEmptyStreams);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break;
|
case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break;
|
||||||
@@ -1312,7 +1328,7 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
ReadBytes(db.SecureBuf + offset, db.SecureOffsets[i + 1] - offset);
|
ReadBytes(db.SecureBuf + offset, db.SecureOffsets[i + 1] - offset);
|
||||||
}
|
}
|
||||||
db.SecureIDs.Clear();
|
db.SecureIDs.Clear();
|
||||||
for (unsigned i = 0; i < db.Files.Size(); i++)
|
for (unsigned i = 0; i < numFiles; i++)
|
||||||
{
|
{
|
||||||
db.SecureIDs.Add(ReadNum());
|
db.SecureIDs.Add(ReadNum());
|
||||||
// db.SecureIDs.Add(ReadUInt32());
|
// db.SecureIDs.Add(ReadUInt32());
|
||||||
@@ -1337,7 +1353,7 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
if (isKnownType)
|
if (isKnownType)
|
||||||
{
|
{
|
||||||
if (addPropIdToList)
|
if (addPropIdToList)
|
||||||
db.ArcInfo.FileInfoPopIDs.Add(type);
|
db.ArcInfo.FileInfoPopIDs.Add(type2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1357,19 +1373,21 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
CNum emptyFileIndex = 0;
|
CNum emptyFileIndex = 0;
|
||||||
CNum sizeIndex = 0;
|
CNum sizeIndex = 0;
|
||||||
|
|
||||||
CNum numAntiItems = 0;
|
const CNum numAntiItems = BoolVector_CountSum(antiFileVector);
|
||||||
for (i = 0; i < numEmptyStreams; i++)
|
|
||||||
if (antiFileVector[i])
|
|
||||||
numAntiItems++;
|
|
||||||
|
|
||||||
for (i = 0; i < numFiles; i++)
|
if (numAntiItems != 0)
|
||||||
|
db.IsAnti.ClearAndSetSize(numFiles);
|
||||||
|
|
||||||
|
db.Files.ClearAndSetSize(numFiles);
|
||||||
|
|
||||||
|
for (CNum i = 0; i < numFiles; i++)
|
||||||
{
|
{
|
||||||
CFileItem &file = db.Files[i];
|
CFileItem &file = db.Files[i];
|
||||||
bool isAnti;
|
bool isAnti;
|
||||||
file.HasStream = !emptyStreamVector[i];
|
|
||||||
file.Crc = 0;
|
file.Crc = 0;
|
||||||
if (file.HasStream)
|
if (!BoolVector_Item_IsValidAndTrue(emptyStreamVector, i))
|
||||||
{
|
{
|
||||||
|
file.HasStream = true;
|
||||||
file.IsDir = false;
|
file.IsDir = false;
|
||||||
isAnti = false;
|
isAnti = false;
|
||||||
file.Size = unpackSizes[sizeIndex];
|
file.Size = unpackSizes[sizeIndex];
|
||||||
@@ -1380,26 +1398,31 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
file.IsDir = !emptyFileVector[emptyFileIndex];
|
file.HasStream = false;
|
||||||
isAnti = antiFileVector[emptyFileIndex];
|
file.IsDir = !BoolVector_Item_IsValidAndTrue(emptyFileVector, emptyFileIndex);
|
||||||
|
isAnti = BoolVector_Item_IsValidAndTrue(antiFileVector, emptyFileIndex);
|
||||||
emptyFileIndex++;
|
emptyFileIndex++;
|
||||||
file.Size = 0;
|
file.Size = 0;
|
||||||
file.CrcDefined = false;
|
file.CrcDefined = false;
|
||||||
}
|
}
|
||||||
if (numAntiItems != 0)
|
if (numAntiItems != 0)
|
||||||
db.IsAnti.Add(isAnti);
|
db.IsAnti[i] = isAnti;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
db.FillLinks();
|
db.FillLinks();
|
||||||
/*
|
|
||||||
if (type != NID::kEnd)
|
if (type != NID::kEnd || _inByteBack->GetRem() != 0)
|
||||||
ThrowIncorrect();
|
{
|
||||||
if (_inByteBack->GetRem() != 0)
|
db.UnsupportedFeatureWarning = true;
|
||||||
ThrowIncorrect();
|
// ThrowIncorrect();
|
||||||
*/
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CDbEx::FillLinks()
|
void CDbEx::FillLinks()
|
||||||
{
|
{
|
||||||
FolderStartFileIndex.Alloc(NumFolders);
|
FolderStartFileIndex.Alloc(NumFolders);
|
||||||
@@ -1461,6 +1484,7 @@ void CDbEx::FillLinks()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT CInArchive::ReadDatabase2(
|
HRESULT CInArchive::ReadDatabase2(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
CDbEx &db
|
CDbEx &db
|
||||||
@@ -1605,6 +1629,7 @@ HRESULT CInArchive::ReadDatabase2(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT CInArchive::ReadDatabase(
|
HRESULT CInArchive::ReadDatabase(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
CDbEx &db
|
CDbEx &db
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ struct CDatabase: public CFolders
|
|||||||
CUInt64DefVector ATime;
|
CUInt64DefVector ATime;
|
||||||
CUInt64DefVector MTime;
|
CUInt64DefVector MTime;
|
||||||
CUInt64DefVector StartPos;
|
CUInt64DefVector StartPos;
|
||||||
|
CUInt32DefVector Attrib;
|
||||||
CBoolVector IsAnti;
|
CBoolVector IsAnti;
|
||||||
/*
|
/*
|
||||||
CBoolVector IsAux;
|
CBoolVector IsAux;
|
||||||
@@ -146,6 +147,7 @@ struct CDatabase: public CFolders
|
|||||||
ATime.Clear();
|
ATime.Clear();
|
||||||
MTime.Clear();
|
MTime.Clear();
|
||||||
StartPos.Clear();
|
StartPos.Clear();
|
||||||
|
Attrib.Clear();
|
||||||
IsAnti.Clear();
|
IsAnti.Clear();
|
||||||
// IsAux.Clear();
|
// IsAux.Clear();
|
||||||
}
|
}
|
||||||
@@ -369,6 +371,8 @@ class CInArchive
|
|||||||
void SkipData() { _inByteBack->SkipData(); }
|
void SkipData() { _inByteBack->SkipData(); }
|
||||||
void WaitId(UInt64 id);
|
void WaitId(UInt64 id);
|
||||||
|
|
||||||
|
void Read_UInt32_Vector(CUInt32DefVector &v);
|
||||||
|
|
||||||
void ReadArchiveProperties(CInArchiveInfo &archiveInfo);
|
void ReadArchiveProperties(CInArchiveInfo &archiveInfo);
|
||||||
void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs);
|
void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs);
|
||||||
|
|
||||||
|
|||||||
@@ -26,12 +26,14 @@ struct CCoderInfo
|
|||||||
bool IsSimpleCoder() const { return NumStreams == 1; }
|
bool IsSimpleCoder() const { return NumStreams == 1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CBond
|
struct CBond
|
||||||
{
|
{
|
||||||
UInt32 PackIndex;
|
UInt32 PackIndex;
|
||||||
UInt32 UnpackIndex;
|
UInt32 UnpackIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CFolder
|
struct CFolder
|
||||||
{
|
{
|
||||||
CLASS_NO_COPY(CFolder)
|
CLASS_NO_COPY(CFolder)
|
||||||
@@ -87,6 +89,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CUInt32DefVector
|
struct CUInt32DefVector
|
||||||
{
|
{
|
||||||
CBoolVector Defs;
|
CBoolVector Defs;
|
||||||
@@ -110,9 +113,25 @@ struct CUInt32DefVector
|
|||||||
Vals.ReserveDown();
|
Vals.ReserveDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GetItem(unsigned index, UInt32 &value) const
|
||||||
|
{
|
||||||
|
if (index < Defs.Size() && Defs[index])
|
||||||
|
{
|
||||||
|
value = Vals[index];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
value = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool ValidAndDefined(unsigned i) const { return i < Defs.Size() && Defs[i]; }
|
bool ValidAndDefined(unsigned i) const { return i < Defs.Size() && Defs[i]; }
|
||||||
|
|
||||||
|
bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; }
|
||||||
|
|
||||||
|
void SetItem(unsigned index, bool defined, UInt32 value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CUInt64DefVector
|
struct CUInt64DefVector
|
||||||
{
|
{
|
||||||
CBoolVector Defs;
|
CBoolVector Defs;
|
||||||
@@ -141,15 +160,15 @@ struct CUInt64DefVector
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetItem(unsigned index, bool defined, UInt64 value);
|
|
||||||
|
|
||||||
bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; }
|
bool CheckSize(unsigned size) const { return Defs.Size() == size || Defs.Size() == 0; }
|
||||||
|
|
||||||
|
void SetItem(unsigned index, bool defined, UInt64 value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CFileItem
|
struct CFileItem
|
||||||
{
|
{
|
||||||
UInt64 Size;
|
UInt64 Size;
|
||||||
UInt32 Attrib;
|
|
||||||
UInt32 Crc;
|
UInt32 Crc;
|
||||||
/*
|
/*
|
||||||
int Parent;
|
int Parent;
|
||||||
@@ -159,23 +178,23 @@ struct CFileItem
|
|||||||
// stream in some folder. It can be empty stream
|
// stream in some folder. It can be empty stream
|
||||||
bool IsDir;
|
bool IsDir;
|
||||||
bool CrcDefined;
|
bool CrcDefined;
|
||||||
bool AttribDefined;
|
|
||||||
|
/*
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
HasStream = true;
|
||||||
|
IsDir = false;
|
||||||
|
CrcDefined = false;
|
||||||
|
}
|
||||||
|
|
||||||
CFileItem():
|
CFileItem():
|
||||||
/*
|
// Parent(-1),
|
||||||
Parent(-1),
|
// IsAltStream(false),
|
||||||
IsAltStream(false),
|
|
||||||
*/
|
|
||||||
HasStream(true),
|
HasStream(true),
|
||||||
IsDir(false),
|
IsDir(false),
|
||||||
CrcDefined(false),
|
CrcDefined(false),
|
||||||
AttribDefined(false)
|
|
||||||
{}
|
{}
|
||||||
void SetAttrib(UInt32 attrib)
|
*/
|
||||||
{
|
|
||||||
AttribDefined = true;
|
|
||||||
Attrib = attrib;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -330,13 +330,11 @@ void COutArchive::WritePropBoolVector(Byte id, const CBoolVector &boolVector)
|
|||||||
WriteBoolVector(boolVector);
|
WriteBoolVector(boolVector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned BoolVector_CountSum(const CBoolVector &v);
|
||||||
|
|
||||||
void COutArchive::WriteHashDigests(const CUInt32DefVector &digests)
|
void COutArchive::WriteHashDigests(const CUInt32DefVector &digests)
|
||||||
{
|
{
|
||||||
unsigned numDefined = 0;
|
const unsigned numDefined = BoolVector_CountSum(digests.Defs);
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < digests.Defs.Size(); i++)
|
|
||||||
if (digests.Defs[i])
|
|
||||||
numDefined++;
|
|
||||||
if (numDefined == 0)
|
if (numDefined == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -348,7 +346,8 @@ void COutArchive::WriteHashDigests(const CUInt32DefVector &digests)
|
|||||||
WriteByte(0);
|
WriteByte(0);
|
||||||
WriteBoolVector(digests.Defs);
|
WriteBoolVector(digests.Defs);
|
||||||
}
|
}
|
||||||
for (i = 0; i < digests.Defs.Size(); i++)
|
|
||||||
|
for (unsigned i = 0; i < digests.Defs.Size(); i++)
|
||||||
if (digests.Defs[i])
|
if (digests.Defs[i])
|
||||||
WriteUInt32(digests.Vals[i]);
|
WriteUInt32(digests.Vals[i]);
|
||||||
}
|
}
|
||||||
@@ -453,10 +452,12 @@ void COutArchive::WriteSubStreamsInfo(const CObjectVector<CFolder> &folders,
|
|||||||
|
|
||||||
// 7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field.
|
// 7-Zip 4.50 - 4.58 contain BUG, so they do not support .7z archives with Unknown field.
|
||||||
|
|
||||||
void COutArchive::SkipAlign(unsigned pos, unsigned alignSize)
|
void COutArchive::SkipToAligned(unsigned pos, unsigned alignShifts)
|
||||||
{
|
{
|
||||||
if (!_useAlign)
|
if (!_useAlign)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const unsigned alignSize = (unsigned)1 << alignShifts;
|
||||||
pos += (unsigned)GetPos();
|
pos += (unsigned)GetPos();
|
||||||
pos &= (alignSize - 1);
|
pos &= (alignSize - 1);
|
||||||
if (pos == 0)
|
if (pos == 0)
|
||||||
@@ -471,11 +472,11 @@ void COutArchive::SkipAlign(unsigned pos, unsigned alignSize)
|
|||||||
WriteByte(0);
|
WriteByte(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize)
|
void COutArchive::WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts)
|
||||||
{
|
{
|
||||||
const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v);
|
const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v);
|
||||||
const UInt64 dataSize = (UInt64)numDefined * itemSize + bvSize + 2;
|
const UInt64 dataSize = ((UInt64)numDefined << itemSizeShifts) + bvSize + 2;
|
||||||
SkipAlign(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSize);
|
SkipToAligned(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSizeShifts);
|
||||||
|
|
||||||
WriteByte(type);
|
WriteByte(type);
|
||||||
WriteNumber(dataSize);
|
WriteNumber(dataSize);
|
||||||
@@ -486,24 +487,18 @@ void COutArchive::WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefin
|
|||||||
WriteByte(0);
|
WriteByte(0);
|
||||||
WriteBoolVector(v);
|
WriteBoolVector(v);
|
||||||
}
|
}
|
||||||
WriteByte(0);
|
WriteByte(0); // 0 means no switching to external stream
|
||||||
}
|
}
|
||||||
|
|
||||||
void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type)
|
void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type)
|
||||||
{
|
{
|
||||||
unsigned numDefined = 0;
|
const unsigned numDefined = BoolVector_CountSum(v.Defs);
|
||||||
|
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < v.Defs.Size(); i++)
|
|
||||||
if (v.Defs[i])
|
|
||||||
numDefined++;
|
|
||||||
|
|
||||||
if (numDefined == 0)
|
if (numDefined == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WriteAlignedBoolHeader(v.Defs, numDefined, type, 8);
|
WriteAlignedBools(v.Defs, numDefined, type, 3);
|
||||||
|
|
||||||
for (i = 0; i < v.Defs.Size(); i++)
|
for (unsigned i = 0; i < v.Defs.Size(); i++)
|
||||||
if (v.Defs[i])
|
if (v.Defs[i])
|
||||||
WriteUInt64(v.Vals[i]);
|
WriteUInt64(v.Vals[i]);
|
||||||
}
|
}
|
||||||
@@ -520,7 +515,7 @@ HRESULT COutArchive::EncodeStream(
|
|||||||
outFolders.FolderUnpackCRCs.Vals.Add(CrcCalc(data, data.Size()));
|
outFolders.FolderUnpackCRCs.Vals.Add(CrcCalc(data, data.Size()));
|
||||||
// outFolders.NumUnpackStreamsVector.Add(1);
|
// outFolders.NumUnpackStreamsVector.Add(1);
|
||||||
UInt64 dataSize64 = data.Size();
|
UInt64 dataSize64 = data.Size();
|
||||||
UInt64 unpackSize;
|
UInt64 unpackSize = data.Size();
|
||||||
RINOK(encoder.Encode(
|
RINOK(encoder.Encode(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
stream,
|
stream,
|
||||||
@@ -540,13 +535,13 @@ void COutArchive::WriteHeader(
|
|||||||
*/
|
*/
|
||||||
_useAlign = true;
|
_useAlign = true;
|
||||||
|
|
||||||
unsigned i;
|
{
|
||||||
|
UInt64 packSize = 0;
|
||||||
UInt64 packedSize = 0;
|
FOR_VECTOR (i, db.PackSizes)
|
||||||
for (i = 0; i < db.PackSizes.Size(); i++)
|
packSize += db.PackSizes[i];
|
||||||
packedSize += db.PackSizes[i];
|
headerOffset = packSize;
|
||||||
|
}
|
||||||
|
|
||||||
headerOffset = packedSize;
|
|
||||||
|
|
||||||
WriteByte(NID::kHeader);
|
WriteByte(NID::kHeader);
|
||||||
|
|
||||||
@@ -560,7 +555,7 @@ void COutArchive::WriteHeader(
|
|||||||
|
|
||||||
CRecordVector<UInt64> unpackSizes;
|
CRecordVector<UInt64> unpackSizes;
|
||||||
CUInt32DefVector digests;
|
CUInt32DefVector digests;
|
||||||
for (i = 0; i < db.Files.Size(); i++)
|
FOR_VECTOR (i, db.Files)
|
||||||
{
|
{
|
||||||
const CFileItem &file = db.Files[i];
|
const CFileItem &file = db.Files[i];
|
||||||
if (!file.HasStream)
|
if (!file.HasStream)
|
||||||
@@ -588,14 +583,17 @@ void COutArchive::WriteHeader(
|
|||||||
CBoolVector emptyStreamVector;
|
CBoolVector emptyStreamVector;
|
||||||
emptyStreamVector.ClearAndSetSize(db.Files.Size());
|
emptyStreamVector.ClearAndSetSize(db.Files.Size());
|
||||||
unsigned numEmptyStreams = 0;
|
unsigned numEmptyStreams = 0;
|
||||||
for (i = 0; i < db.Files.Size(); i++)
|
{
|
||||||
if (db.Files[i].HasStream)
|
FOR_VECTOR (i, db.Files)
|
||||||
emptyStreamVector[i] = false;
|
if (db.Files[i].HasStream)
|
||||||
else
|
emptyStreamVector[i] = false;
|
||||||
{
|
else
|
||||||
emptyStreamVector[i] = true;
|
{
|
||||||
numEmptyStreams++;
|
emptyStreamVector[i] = true;
|
||||||
}
|
numEmptyStreams++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (numEmptyStreams != 0)
|
if (numEmptyStreams != 0)
|
||||||
{
|
{
|
||||||
WritePropBoolVector(NID::kEmptyStream, emptyStreamVector);
|
WritePropBoolVector(NID::kEmptyStream, emptyStreamVector);
|
||||||
@@ -605,7 +603,8 @@ void COutArchive::WriteHeader(
|
|||||||
antiVector.ClearAndSetSize(numEmptyStreams);
|
antiVector.ClearAndSetSize(numEmptyStreams);
|
||||||
bool thereAreEmptyFiles = false, thereAreAntiItems = false;
|
bool thereAreEmptyFiles = false, thereAreAntiItems = false;
|
||||||
unsigned cur = 0;
|
unsigned cur = 0;
|
||||||
for (i = 0; i < db.Files.Size(); i++)
|
|
||||||
|
FOR_VECTOR (i, db.Files)
|
||||||
{
|
{
|
||||||
const CFileItem &file = db.Files[i];
|
const CFileItem &file = db.Files[i];
|
||||||
if (file.HasStream)
|
if (file.HasStream)
|
||||||
@@ -644,7 +643,7 @@ void COutArchive::WriteHeader(
|
|||||||
if (numDefined > 0)
|
if (numDefined > 0)
|
||||||
{
|
{
|
||||||
namesDataSize++;
|
namesDataSize++;
|
||||||
SkipAlign(2 + GetBigNumberSize(namesDataSize), 16);
|
SkipToAligned(2 + GetBigNumberSize(namesDataSize), 4);
|
||||||
|
|
||||||
WriteByte(NID::kName);
|
WriteByte(NID::kName);
|
||||||
WriteNumber(namesDataSize);
|
WriteNumber(namesDataSize);
|
||||||
@@ -669,24 +668,15 @@ void COutArchive::WriteHeader(
|
|||||||
|
|
||||||
{
|
{
|
||||||
/* ---------- Write Attrib ---------- */
|
/* ---------- Write Attrib ---------- */
|
||||||
CBoolVector boolVector;
|
const unsigned numDefined = BoolVector_CountSum(db.Attrib.Defs);
|
||||||
boolVector.ClearAndSetSize(db.Files.Size());
|
|
||||||
unsigned numDefined = 0;
|
|
||||||
for (i = 0; i < db.Files.Size(); i++)
|
|
||||||
{
|
|
||||||
bool defined = db.Files[i].AttribDefined;
|
|
||||||
boolVector[i] = defined;
|
|
||||||
if (defined)
|
|
||||||
numDefined++;
|
|
||||||
}
|
|
||||||
if (numDefined != 0)
|
if (numDefined != 0)
|
||||||
{
|
{
|
||||||
WriteAlignedBoolHeader(boolVector, numDefined, NID::kWinAttrib, 4);
|
WriteAlignedBools(db.Attrib.Defs, numDefined, NID::kWinAttrib, 2);
|
||||||
for (i = 0; i < db.Files.Size(); i++)
|
FOR_VECTOR (i, db.Attrib.Defs)
|
||||||
{
|
{
|
||||||
const CFileItem &file = db.Files[i];
|
if (db.Attrib.Defs[i])
|
||||||
if (file.AttribDefined)
|
WriteUInt32(db.Attrib.Vals[i]);
|
||||||
WriteUInt32(file.Attrib);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -694,18 +684,8 @@ void COutArchive::WriteHeader(
|
|||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
// ---------- Write IsAux ----------
|
// ---------- Write IsAux ----------
|
||||||
unsigned numAux = 0;
|
if (BoolVector_CountSum(db.IsAux) != 0)
|
||||||
const CBoolVector &isAux = db.IsAux;
|
WritePropBoolVector(NID::kIsAux, db.IsAux);
|
||||||
for (i = 0; i < isAux.Size(); i++)
|
|
||||||
if (isAux[i])
|
|
||||||
numAux++;
|
|
||||||
if (numAux > 0)
|
|
||||||
{
|
|
||||||
const unsigned bvSize = Bv_GetSizeInBytes(isAux);
|
|
||||||
WriteByte(NID::kIsAux);
|
|
||||||
WriteNumber(bvSize);
|
|
||||||
WriteBoolVector(isAux);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -726,10 +706,10 @@ void COutArchive::WriteHeader(
|
|||||||
}
|
}
|
||||||
if (numParentLinks > 0)
|
if (numParentLinks > 0)
|
||||||
{
|
{
|
||||||
// WriteAlignedBoolHeader(boolVector, numDefined, NID::kParent, 4);
|
// WriteAlignedBools(boolVector, numDefined, NID::kParent, 2);
|
||||||
const unsigned bvSize = (numIsDir == boolVector.Size()) ? 0 : Bv_GetSizeInBytes(boolVector);
|
const unsigned bvSize = (numIsDir == boolVector.Size()) ? 0 : Bv_GetSizeInBytes(boolVector);
|
||||||
const UInt64 dataSize = (UInt64)db.Files.Size() * 4 + bvSize + 1;
|
const UInt64 dataSize = (UInt64)db.Files.Size() * 4 + bvSize + 1;
|
||||||
SkipAlign(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 4);
|
SkipToAligned(2 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), 2);
|
||||||
|
|
||||||
WriteByte(NID::kParent);
|
WriteByte(NID::kParent);
|
||||||
WriteNumber(dataSize);
|
WriteNumber(dataSize);
|
||||||
@@ -757,7 +737,7 @@ void COutArchive::WriteHeader(
|
|||||||
// secureDataSize += db.SecureIDs.Size() * 4;
|
// secureDataSize += db.SecureIDs.Size() * 4;
|
||||||
for (i = 0; i < db.SecureIDs.Size(); i++)
|
for (i = 0; i < db.SecureIDs.Size(); i++)
|
||||||
secureDataSize += GetBigNumberSize(db.SecureIDs[i]);
|
secureDataSize += GetBigNumberSize(db.SecureIDs[i]);
|
||||||
SkipAlign(2 + GetBigNumberSize(secureDataSize), 4);
|
SkipToAligned(2 + GetBigNumberSize(secureDataSize), 2);
|
||||||
WriteByte(NID::kNtSecure);
|
WriteByte(NID::kNtSecure);
|
||||||
WriteNumber(secureDataSize);
|
WriteNumber(secureDataSize);
|
||||||
WriteByte(0);
|
WriteByte(0);
|
||||||
@@ -880,6 +860,18 @@ HRESULT COutArchive::WriteDatabase(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CUInt32DefVector::SetItem(unsigned index, bool defined, UInt32 value)
|
||||||
|
{
|
||||||
|
while (index >= Defs.Size())
|
||||||
|
Defs.Add(false);
|
||||||
|
Defs[index] = defined;
|
||||||
|
if (!defined)
|
||||||
|
return;
|
||||||
|
while (index >= Vals.Size())
|
||||||
|
Vals.Add(0);
|
||||||
|
Vals[index] = value;
|
||||||
|
}
|
||||||
|
|
||||||
void CUInt64DefVector::SetItem(unsigned index, bool defined, UInt64 value)
|
void CUInt64DefVector::SetItem(unsigned index, bool defined, UInt64 value)
|
||||||
{
|
{
|
||||||
while (index >= Defs.Size())
|
while (index >= Defs.Size())
|
||||||
@@ -899,6 +891,7 @@ void CArchiveDatabaseOut::AddFile(const CFileItem &file, const CFileItem2 &file2
|
|||||||
ATime.SetItem(index, file2.ATimeDefined, file2.ATime);
|
ATime.SetItem(index, file2.ATimeDefined, file2.ATime);
|
||||||
MTime.SetItem(index, file2.MTimeDefined, file2.MTime);
|
MTime.SetItem(index, file2.MTimeDefined, file2.MTime);
|
||||||
StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos);
|
StartPos.SetItem(index, file2.StartPosDefined, file2.StartPos);
|
||||||
|
Attrib.SetItem(index, file2.AttribDefined, file2.Attrib);
|
||||||
SetItem_Anti(index, file2.IsAnti);
|
SetItem_Anti(index, file2.IsAnti);
|
||||||
// SetItem_Aux(index, file2.IsAux);
|
// SetItem_Aux(index, file2.IsAux);
|
||||||
Names.Add(name);
|
Names.Add(name);
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ public:
|
|||||||
size_t GetPos() const { return _pos; }
|
size_t GetPos() const { return _pos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CHeaderOptions
|
struct CHeaderOptions
|
||||||
{
|
{
|
||||||
bool CompressMainHeader;
|
bool CompressMainHeader;
|
||||||
@@ -71,24 +72,31 @@ struct CFileItem2
|
|||||||
UInt64 ATime;
|
UInt64 ATime;
|
||||||
UInt64 MTime;
|
UInt64 MTime;
|
||||||
UInt64 StartPos;
|
UInt64 StartPos;
|
||||||
|
UInt32 Attrib;
|
||||||
|
|
||||||
bool CTimeDefined;
|
bool CTimeDefined;
|
||||||
bool ATimeDefined;
|
bool ATimeDefined;
|
||||||
bool MTimeDefined;
|
bool MTimeDefined;
|
||||||
bool StartPosDefined;
|
bool StartPosDefined;
|
||||||
|
bool AttribDefined;
|
||||||
bool IsAnti;
|
bool IsAnti;
|
||||||
// bool IsAux;
|
// bool IsAux;
|
||||||
|
|
||||||
|
/*
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
CTimeDefined = false;
|
CTimeDefined = false;
|
||||||
ATimeDefined = false;
|
ATimeDefined = false;
|
||||||
MTimeDefined = false;
|
MTimeDefined = false;
|
||||||
StartPosDefined = false;
|
StartPosDefined = false;
|
||||||
|
AttribDefined = false;
|
||||||
IsAnti = false;
|
IsAnti = false;
|
||||||
// IsAux = false;
|
// IsAux = false;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct COutFolders
|
struct COutFolders
|
||||||
{
|
{
|
||||||
CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only.
|
CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only.
|
||||||
@@ -111,6 +119,7 @@ struct COutFolders
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CArchiveDatabaseOut: public COutFolders
|
struct CArchiveDatabaseOut: public COutFolders
|
||||||
{
|
{
|
||||||
CRecordVector<UInt64> PackSizes;
|
CRecordVector<UInt64> PackSizes;
|
||||||
@@ -123,10 +132,11 @@ struct CArchiveDatabaseOut: public COutFolders
|
|||||||
CUInt64DefVector ATime;
|
CUInt64DefVector ATime;
|
||||||
CUInt64DefVector MTime;
|
CUInt64DefVector MTime;
|
||||||
CUInt64DefVector StartPos;
|
CUInt64DefVector StartPos;
|
||||||
CRecordVector<bool> IsAnti;
|
CUInt32DefVector Attrib;
|
||||||
|
CBoolVector IsAnti;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
CRecordVector<bool> IsAux;
|
CBoolVector IsAux;
|
||||||
|
|
||||||
CByteBuffer SecureBuf;
|
CByteBuffer SecureBuf;
|
||||||
CRecordVector<UInt32> SecureSizes;
|
CRecordVector<UInt32> SecureSizes;
|
||||||
@@ -154,6 +164,7 @@ struct CArchiveDatabaseOut: public COutFolders
|
|||||||
ATime.Clear();
|
ATime.Clear();
|
||||||
MTime.Clear();
|
MTime.Clear();
|
||||||
StartPos.Clear();
|
StartPos.Clear();
|
||||||
|
Attrib.Clear();
|
||||||
IsAnti.Clear();
|
IsAnti.Clear();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -176,6 +187,7 @@ struct CArchiveDatabaseOut: public COutFolders
|
|||||||
ATime.ReserveDown();
|
ATime.ReserveDown();
|
||||||
MTime.ReserveDown();
|
MTime.ReserveDown();
|
||||||
StartPos.ReserveDown();
|
StartPos.ReserveDown();
|
||||||
|
Attrib.ReserveDown();
|
||||||
IsAnti.ReserveDown();
|
IsAnti.ReserveDown();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -196,11 +208,12 @@ struct CArchiveDatabaseOut: public COutFolders
|
|||||||
{
|
{
|
||||||
unsigned size = Files.Size();
|
unsigned size = Files.Size();
|
||||||
return (
|
return (
|
||||||
CTime.CheckSize(size) &&
|
CTime.CheckSize(size)
|
||||||
ATime.CheckSize(size) &&
|
&& ATime.CheckSize(size)
|
||||||
MTime.CheckSize(size) &&
|
&& MTime.CheckSize(size)
|
||||||
StartPos.CheckSize(size) &&
|
&& StartPos.CheckSize(size)
|
||||||
(size == IsAnti.Size() || IsAnti.Size() == 0));
|
&& Attrib.CheckSize(size)
|
||||||
|
&& (size == IsAnti.Size() || IsAnti.Size() == 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
|
bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
|
||||||
@@ -224,6 +237,7 @@ struct CArchiveDatabaseOut: public COutFolders
|
|||||||
void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name);
|
void AddFile(const CFileItem &file, const CFileItem2 &file2, const UString &name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class COutArchive
|
class COutArchive
|
||||||
{
|
{
|
||||||
UInt64 _prefixHeaderPos;
|
UInt64 _prefixHeaderPos;
|
||||||
@@ -261,8 +275,8 @@ class COutArchive
|
|||||||
const CRecordVector<UInt64> &unpackSizes,
|
const CRecordVector<UInt64> &unpackSizes,
|
||||||
const CUInt32DefVector &digests);
|
const CUInt32DefVector &digests);
|
||||||
|
|
||||||
void SkipAlign(unsigned pos, unsigned alignSize);
|
void SkipToAligned(unsigned pos, unsigned alignShifts);
|
||||||
void WriteAlignedBoolHeader(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSize);
|
void WriteAlignedBools(const CBoolVector &v, unsigned numDefined, Byte type, unsigned itemSizeShifts);
|
||||||
void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
|
void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
|
||||||
|
|
||||||
HRESULT EncodeStream(
|
HRESULT EncodeStream(
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ struct CFilterMode
|
|||||||
{
|
{
|
||||||
if (Id == k_IA64)
|
if (Id == k_IA64)
|
||||||
Delta = 16;
|
Delta = 16;
|
||||||
else if (Id == k_ARM || Id == k_PPC || Id == k_PPC)
|
else if (Id == k_ARM || Id == k_PPC || Id == k_SPARC)
|
||||||
Delta = 4;
|
Delta = 4;
|
||||||
else if (Id == k_ARMT)
|
else if (Id == k_ARMT)
|
||||||
Delta = 2;
|
Delta = 2;
|
||||||
@@ -779,7 +779,7 @@ struct CSolidGroup
|
|||||||
CRecordVector<CFolderRepack> folderRefs;
|
CRecordVector<CFolderRepack> folderRefs;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *g_ExeExts[] =
|
static const char * const g_ExeExts[] =
|
||||||
{
|
{
|
||||||
"dll"
|
"dll"
|
||||||
, "exe"
|
, "exe"
|
||||||
@@ -1088,18 +1088,23 @@ static HRESULT MakeExeMethod(CCompressionMethodMode &mode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void FromUpdateItemToFileItem(const CUpdateItem &ui,
|
static void UpdateItem_To_FileItem2(const CUpdateItem &ui, CFileItem2 &file2)
|
||||||
CFileItem &file, CFileItem2 &file2)
|
|
||||||
{
|
{
|
||||||
if (ui.AttribDefined)
|
file2.Attrib = ui.Attrib; file2.AttribDefined = ui.AttribDefined;
|
||||||
file.SetAttrib(ui.Attrib);
|
|
||||||
|
|
||||||
file2.CTime = ui.CTime; file2.CTimeDefined = ui.CTimeDefined;
|
file2.CTime = ui.CTime; file2.CTimeDefined = ui.CTimeDefined;
|
||||||
file2.ATime = ui.ATime; file2.ATimeDefined = ui.ATimeDefined;
|
file2.ATime = ui.ATime; file2.ATimeDefined = ui.ATimeDefined;
|
||||||
file2.MTime = ui.MTime; file2.MTimeDefined = ui.MTimeDefined;
|
file2.MTime = ui.MTime; file2.MTimeDefined = ui.MTimeDefined;
|
||||||
file2.IsAnti = ui.IsAnti;
|
file2.IsAnti = ui.IsAnti;
|
||||||
// file2.IsAux = false;
|
// file2.IsAux = false;
|
||||||
file2.StartPosDefined = false;
|
file2.StartPosDefined = false;
|
||||||
|
// file2.StartPos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void UpdateItem_To_FileItem(const CUpdateItem &ui,
|
||||||
|
CFileItem &file, CFileItem2 &file2)
|
||||||
|
{
|
||||||
|
UpdateItem_To_FileItem2(ui, file2);
|
||||||
|
|
||||||
file.Size = ui.Size;
|
file.Size = ui.Size;
|
||||||
file.IsDir = ui.IsDir;
|
file.IsDir = ui.IsDir;
|
||||||
@@ -1107,6 +1112,8 @@ static void FromUpdateItemToFileItem(const CUpdateItem &ui,
|
|||||||
// file.IsAltStream = ui.IsAltStream;
|
// file.IsAltStream = ui.IsAltStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CRepackInStreamWithSizes:
|
class CRepackInStreamWithSizes:
|
||||||
public ISequentialInStream,
|
public ISequentialInStream,
|
||||||
public ICompressGetSubStreamSize,
|
public ICompressGetSubStreamSize,
|
||||||
@@ -1437,6 +1444,7 @@ public:
|
|||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
|
|
||||||
|
bool dataAfterEnd_Error;
|
||||||
HRESULT Result;
|
HRESULT Result;
|
||||||
CMyComPtr<IInStream> InStream;
|
CMyComPtr<IInStream> InStream;
|
||||||
|
|
||||||
@@ -1479,7 +1487,9 @@ void CThreadDecoder::Execute()
|
|||||||
bool passwordIsDefined = false;
|
bool passwordIsDefined = false;
|
||||||
UString password;
|
UString password;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
dataAfterEnd_Error = false;
|
||||||
|
|
||||||
Result = Decoder.Decode(
|
Result = Decoder.Decode(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
InStream,
|
InStream,
|
||||||
@@ -1491,12 +1501,15 @@ void CThreadDecoder::Execute()
|
|||||||
|
|
||||||
Fos,
|
Fos,
|
||||||
NULL, // compressProgress
|
NULL, // compressProgress
|
||||||
|
|
||||||
NULL // *inStreamMainRes
|
NULL // *inStreamMainRes
|
||||||
|
, dataAfterEnd_Error
|
||||||
|
|
||||||
_7Z_DECODER_CRYPRO_VARS
|
_7Z_DECODER_CRYPRO_VARS
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
, MtMode, NumThreads
|
, MtMode, NumThreads
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
@@ -1541,6 +1554,7 @@ static void GetFile(const CDatabase &inDb, unsigned index, CFileItem &file, CFil
|
|||||||
file2.ATimeDefined = inDb.ATime.GetItem(index, file2.ATime);
|
file2.ATimeDefined = inDb.ATime.GetItem(index, file2.ATime);
|
||||||
file2.MTimeDefined = inDb.MTime.GetItem(index, file2.MTime);
|
file2.MTimeDefined = inDb.MTime.GetItem(index, file2.MTime);
|
||||||
file2.StartPosDefined = inDb.StartPos.GetItem(index, file2.StartPos);
|
file2.StartPosDefined = inDb.StartPos.GetItem(index, file2.StartPos);
|
||||||
|
file2.AttribDefined = inDb.Attrib.GetItem(index, file2.Attrib);
|
||||||
file2.IsAnti = inDb.IsItemAnti(index);
|
file2.IsAnti = inDb.IsItemAnti(index);
|
||||||
// file2.IsAux = inDb.IsItemAux(index);
|
// file2.IsAux = inDb.IsItemAux(index);
|
||||||
}
|
}
|
||||||
@@ -1681,17 +1695,18 @@ HRESULT Update(
|
|||||||
}
|
}
|
||||||
|
|
||||||
UInt64 inSizeForReduce = 0;
|
UInt64 inSizeForReduce = 0;
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < updateItems.Size(); i++)
|
|
||||||
{
|
{
|
||||||
const CUpdateItem &ui = updateItems[i];
|
FOR_VECTOR (i, updateItems)
|
||||||
if (ui.NewData)
|
|
||||||
{
|
{
|
||||||
complexity += ui.Size;
|
const CUpdateItem &ui = updateItems[i];
|
||||||
if (numSolidFiles != 1)
|
if (ui.NewData)
|
||||||
inSizeForReduce += ui.Size;
|
{
|
||||||
else if (inSizeForReduce < ui.Size)
|
complexity += ui.Size;
|
||||||
inSizeForReduce = ui.Size;
|
if (numSolidFiles != 1)
|
||||||
|
inSizeForReduce += ui.Size;
|
||||||
|
else if (inSizeForReduce < ui.Size)
|
||||||
|
inSizeForReduce = ui.Size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1753,7 +1768,7 @@ HRESULT Update(
|
|||||||
|
|
||||||
const CCompressionMethodMode &method = *options.Method;
|
const CCompressionMethodMode &method = *options.Method;
|
||||||
|
|
||||||
for (i = 0; i < updateItems.Size(); i++)
|
FOR_VECTOR (i, updateItems)
|
||||||
{
|
{
|
||||||
const CUpdateItem &ui = updateItems[i];
|
const CUpdateItem &ui = updateItems[i];
|
||||||
if (!ui.NewData || !ui.HasStream())
|
if (!ui.NewData || !ui.HasStream())
|
||||||
@@ -1836,7 +1851,7 @@ HRESULT Update(
|
|||||||
continue;
|
continue;
|
||||||
secureID = ui.SecureIndex;
|
secureID = ui.SecureIndex;
|
||||||
if (ui.NewProps)
|
if (ui.NewProps)
|
||||||
FromUpdateItemToFileItem(ui, file, file2);
|
UpdateItem_To_FileItem(ui, file, file2);
|
||||||
else
|
else
|
||||||
GetFile(*db, ui.IndexInArchive, file, file2);
|
GetFile(*db, ui.IndexInArchive, file, file2);
|
||||||
}
|
}
|
||||||
@@ -1857,6 +1872,8 @@ HRESULT Update(
|
|||||||
/* ---------- Write non-AUX dirs and Empty files ---------- */
|
/* ---------- Write non-AUX dirs and Empty files ---------- */
|
||||||
CUIntVector emptyRefs;
|
CUIntVector emptyRefs;
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
for (i = 0; i < updateItems.Size(); i++)
|
for (i = 0; i < updateItems.Size(); i++)
|
||||||
{
|
{
|
||||||
const CUpdateItem &ui = updateItems[i];
|
const CUpdateItem &ui = updateItems[i];
|
||||||
@@ -1884,7 +1901,8 @@ HRESULT Update(
|
|||||||
UString name;
|
UString name;
|
||||||
if (ui.NewProps)
|
if (ui.NewProps)
|
||||||
{
|
{
|
||||||
FromUpdateItemToFileItem(ui, file, file2);
|
UpdateItem_To_FileItem(ui, file, file2);
|
||||||
|
file.CrcDefined = false;
|
||||||
name = ui.Name;
|
name = ui.Name;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1919,7 +1937,8 @@ HRESULT Update(
|
|||||||
const CFilterMode2 &filterMode = filters[groupIndex];
|
const CFilterMode2 &filterMode = filters[groupIndex];
|
||||||
|
|
||||||
CCompressionMethodMode method = *options.Method;
|
CCompressionMethodMode method = *options.Method;
|
||||||
HRESULT res = MakeExeMethod(method, filterMode,
|
{
|
||||||
|
HRESULT res = MakeExeMethod(method, filterMode,
|
||||||
#ifdef _7ZIP_ST
|
#ifdef _7ZIP_ST
|
||||||
false
|
false
|
||||||
#else
|
#else
|
||||||
@@ -1927,7 +1946,8 @@ HRESULT Update(
|
|||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
RINOK(res);
|
RINOK(res);
|
||||||
|
}
|
||||||
|
|
||||||
if (filterMode.Encrypted)
|
if (filterMode.Encrypted)
|
||||||
{
|
{
|
||||||
@@ -2102,6 +2122,8 @@ HRESULT Update(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
CMyComPtr<ISequentialInStream> decodedStream;
|
CMyComPtr<ISequentialInStream> decodedStream;
|
||||||
|
bool dataAfterEnd_Error = false;
|
||||||
|
|
||||||
HRESULT res = threadDecoder.Decoder.Decode(
|
HRESULT res = threadDecoder.Decoder.Decode(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
inStream,
|
inStream,
|
||||||
@@ -2112,13 +2134,16 @@ HRESULT Update(
|
|||||||
|
|
||||||
NULL, // *outStream
|
NULL, // *outStream
|
||||||
NULL, // *compressProgress
|
NULL, // *compressProgress
|
||||||
|
|
||||||
&decodedStream
|
&decodedStream
|
||||||
|
, dataAfterEnd_Error
|
||||||
|
|
||||||
_7Z_DECODER_CRYPRO_VARS
|
_7Z_DECODER_CRYPRO_VARS
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
, false // mtMode
|
, false // mtMode
|
||||||
, 1 // numThreads
|
, 1 // numThreads
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
RINOK(res);
|
RINOK(res);
|
||||||
@@ -2146,6 +2171,7 @@ HRESULT Update(
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curUnpackSize = sizeToEncode;
|
||||||
|
|
||||||
HRESULT encodeRes = encoder.Encode(
|
HRESULT encodeRes = encoder.Encode(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
@@ -2170,16 +2196,19 @@ HRESULT Update(
|
|||||||
|
|
||||||
HRESULT decodeRes = threadDecoder.Result;
|
HRESULT decodeRes = threadDecoder.Result;
|
||||||
// if (res == k_My_HRESULT_CRC_ERROR)
|
// if (res == k_My_HRESULT_CRC_ERROR)
|
||||||
if (decodeRes == S_FALSE)
|
if (decodeRes == S_FALSE || threadDecoder.dataAfterEnd_Error)
|
||||||
{
|
{
|
||||||
if (extractCallback)
|
if (extractCallback)
|
||||||
{
|
{
|
||||||
RINOK(extractCallback->ReportExtractResult(
|
RINOK(extractCallback->ReportExtractResult(
|
||||||
NEventIndexType::kInArcIndex, db->FolderStartFileIndex[folderIndex],
|
NEventIndexType::kInArcIndex, db->FolderStartFileIndex[folderIndex],
|
||||||
// NEventIndexType::kBlockIndex, (UInt32)folderIndex,
|
// NEventIndexType::kBlockIndex, (UInt32)folderIndex,
|
||||||
NExtract::NOperationResult::kDataError));
|
(decodeRes != S_OK ?
|
||||||
|
NExtract::NOperationResult::kDataError :
|
||||||
|
NExtract::NOperationResult::kDataAfterEnd)));
|
||||||
}
|
}
|
||||||
return E_FAIL;
|
if (decodeRes != S_OK)
|
||||||
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
RINOK(decodeRes);
|
RINOK(decodeRes);
|
||||||
if (encodeRes == S_OK)
|
if (encodeRes == S_OK)
|
||||||
@@ -2219,12 +2248,7 @@ HRESULT Update(
|
|||||||
CNum indexInFolder = 0;
|
CNum indexInFolder = 0;
|
||||||
for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++)
|
for (CNum fi = db->FolderStartFileIndex[folderIndex]; indexInFolder < numUnpackStreams; fi++)
|
||||||
{
|
{
|
||||||
CFileItem file;
|
if (db->Files[fi].HasStream)
|
||||||
CFileItem2 file2;
|
|
||||||
GetFile(*db, fi, file, file2);
|
|
||||||
UString name;
|
|
||||||
db->GetPath(fi, name);
|
|
||||||
if (file.HasStream)
|
|
||||||
{
|
{
|
||||||
indexInFolder++;
|
indexInFolder++;
|
||||||
int updateIndex = fileIndexToUpdateIndexMap[fi];
|
int updateIndex = fileIndexToUpdateIndexMap[fi];
|
||||||
@@ -2233,17 +2257,21 @@ HRESULT Update(
|
|||||||
const CUpdateItem &ui = updateItems[updateIndex];
|
const CUpdateItem &ui = updateItems[updateIndex];
|
||||||
if (ui.NewData)
|
if (ui.NewData)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
UString name;
|
||||||
|
CFileItem file;
|
||||||
|
CFileItem2 file2;
|
||||||
|
GetFile(*db, fi, file, file2);
|
||||||
|
|
||||||
if (ui.NewProps)
|
if (ui.NewProps)
|
||||||
{
|
{
|
||||||
CFileItem uf;
|
UpdateItem_To_FileItem2(ui, file2);
|
||||||
FromUpdateItemToFileItem(ui, uf, file2);
|
file.IsDir = ui.IsDir;
|
||||||
uf.Size = file.Size;
|
|
||||||
uf.Crc = file.Crc;
|
|
||||||
uf.CrcDefined = file.CrcDefined;
|
|
||||||
uf.HasStream = file.HasStream;
|
|
||||||
file = uf;
|
|
||||||
name = ui.Name;
|
name = ui.Name;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
db->GetPath(fi, name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
file.Parent = ui.ParentFolderIndex;
|
file.Parent = ui.ParentFolderIndex;
|
||||||
if (ui.TreeFolderIndex >= 0)
|
if (ui.TreeFolderIndex >= 0)
|
||||||
@@ -2266,8 +2294,12 @@ HRESULT Update(
|
|||||||
CRecordVector<CRefItem> refItems;
|
CRecordVector<CRefItem> refItems;
|
||||||
refItems.ClearAndSetSize(numFiles);
|
refItems.ClearAndSetSize(numFiles);
|
||||||
bool sortByType = (options.UseTypeSorting && numSolidFiles > 1);
|
bool sortByType = (options.UseTypeSorting && numSolidFiles > 1);
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
for (i = 0; i < numFiles; i++)
|
for (i = 0; i < numFiles; i++)
|
||||||
refItems[i] = CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType);
|
refItems[i] = CRefItem(group.Indices[i], updateItems[group.Indices[i]], sortByType);
|
||||||
|
|
||||||
CSortParam sortParam;
|
CSortParam sortParam;
|
||||||
// sortParam.TreeFolders = &treeFolders;
|
// sortParam.TreeFolders = &treeFolders;
|
||||||
sortParam.SortByType = sortByType;
|
sortParam.SortByType = sortByType;
|
||||||
@@ -2283,7 +2315,7 @@ HRESULT Update(
|
|||||||
const CUpdateItem &ui = updateItems[index];
|
const CUpdateItem &ui = updateItems[index];
|
||||||
CFileItem file;
|
CFileItem file;
|
||||||
if (ui.NewProps)
|
if (ui.NewProps)
|
||||||
FromUpdateItemToFileItem(ui, file);
|
UpdateItem_To_FileItem(ui, file);
|
||||||
else
|
else
|
||||||
file = db.Files[ui.IndexInArchive];
|
file = db.Files[ui.IndexInArchive];
|
||||||
if (file.IsAnti || file.IsDir)
|
if (file.IsAnti || file.IsDir)
|
||||||
@@ -2327,7 +2359,9 @@ HRESULT Update(
|
|||||||
inStreamSpec->Init(updateCallback, &indices[i], numSubFiles);
|
inStreamSpec->Init(updateCallback, &indices[i], numSubFiles);
|
||||||
|
|
||||||
unsigned startPackIndex = newDatabase.PackSizes.Size();
|
unsigned startPackIndex = newDatabase.PackSizes.Size();
|
||||||
UInt64 curFolderUnpackSize;
|
UInt64 curFolderUnpackSize = totalSize;
|
||||||
|
// curFolderUnpackSize = (UInt64)(Int64)-1;
|
||||||
|
|
||||||
RINOK(encoder.Encode(
|
RINOK(encoder.Encode(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
solidInStream,
|
solidInStream,
|
||||||
@@ -2358,7 +2392,7 @@ HRESULT Update(
|
|||||||
UString name;
|
UString name;
|
||||||
if (ui.NewProps)
|
if (ui.NewProps)
|
||||||
{
|
{
|
||||||
FromUpdateItemToFileItem(ui, file, file2);
|
UpdateItem_To_FileItem(ui, file, file2);
|
||||||
name = ui.Name;
|
name = ui.Name;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2377,7 +2411,7 @@ HRESULT Update(
|
|||||||
{
|
{
|
||||||
skippedSize += ui.Size;
|
skippedSize += ui.Size;
|
||||||
continue;
|
continue;
|
||||||
// file.Name.AddAscii(".locked");
|
// file.Name += ".locked";
|
||||||
}
|
}
|
||||||
|
|
||||||
file.Crc = inStreamSpec->CRCs[subIndex];
|
file.Crc = inStreamSpec->CRCs[subIndex];
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include "../../Common/ComTry.h"
|
#include "../../Common/ComTry.h"
|
||||||
#include "../../Common/Defs.h"
|
#include "../../Common/Defs.h"
|
||||||
#include "../../Common/IntToString.h"
|
|
||||||
|
|
||||||
#include "../../Windows/PropVariant.h"
|
#include "../../Windows/PropVariant.h"
|
||||||
|
|
||||||
@@ -232,7 +231,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
int mainIndex = -1;
|
int mainIndex = -1;
|
||||||
FOR_VECTOR (i, _items)
|
FOR_VECTOR (i, _items)
|
||||||
{
|
{
|
||||||
AString s = GetString(_items[i].Type);
|
AString s (GetString(_items[i].Type));
|
||||||
if (s != "Apple_Free" &&
|
if (s != "Apple_Free" &&
|
||||||
s != "Apple_partition_map")
|
s != "Apple_partition_map")
|
||||||
{
|
{
|
||||||
@@ -279,14 +278,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
{
|
{
|
||||||
case kpidPath:
|
case kpidPath:
|
||||||
{
|
{
|
||||||
AString s = GetString(item.Name);
|
AString s (GetString(item.Name));
|
||||||
if (s.IsEmpty())
|
if (s.IsEmpty())
|
||||||
{
|
s.Add_UInt32(index);
|
||||||
char s2[32];
|
AString type (GetString(item.Type));
|
||||||
ConvertUInt32ToString(index, s2);
|
|
||||||
s = s2;
|
|
||||||
}
|
|
||||||
AString type = GetString(item.Type);
|
|
||||||
if (type == "Apple_HFS")
|
if (type == "Apple_HFS")
|
||||||
type = "hfs";
|
type = "hfs";
|
||||||
if (!type.IsEmpty())
|
if (!type.IsEmpty())
|
||||||
|
|||||||
@@ -343,16 +343,17 @@ HRESULT CHandler::ParseLongNames(IInStream *stream)
|
|||||||
if (item.Size > ((UInt32)1 << 30))
|
if (item.Size > ((UInt32)1 << 30))
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
RINOK(stream->Seek(item.GetDataPos(), STREAM_SEEK_SET, NULL));
|
RINOK(stream->Seek(item.GetDataPos(), STREAM_SEEK_SET, NULL));
|
||||||
size_t size = (size_t)item.Size;
|
const size_t size = (size_t)item.Size;
|
||||||
|
|
||||||
CByteArr p(size);
|
CByteArr p(size);
|
||||||
RINOK(ReadStream_FALSE(stream, p, size));
|
RINOK(ReadStream_FALSE(stream, p, size));
|
||||||
|
|
||||||
for (i = 0; i < _items.Size(); i++)
|
for (i = 0; i < _items.Size(); i++)
|
||||||
{
|
{
|
||||||
CItem &item = _items[i];
|
CItem &item2 = _items[i];
|
||||||
if (item.Name[0] != '/')
|
if (item2.Name[0] != '/')
|
||||||
continue;
|
continue;
|
||||||
const char *ptr = item.Name.Ptr(1);
|
const char *ptr = item2.Name.Ptr(1);
|
||||||
const char *end;
|
const char *end;
|
||||||
UInt32 pos = ConvertStringToUInt32(ptr, &end);
|
UInt32 pos = ConvertStringToUInt32(ptr, &end);
|
||||||
if (*end != 0 || end == ptr)
|
if (*end != 0 || end == ptr)
|
||||||
@@ -369,8 +370,9 @@ HRESULT CHandler::ParseLongNames(IInStream *stream)
|
|||||||
break;
|
break;
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
item.Name.SetFrom((const char *)(p + start), pos - start);
|
item2.Name.SetFrom((const char *)(p + start), pos - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
_longNames_FileIndex = fileIndex;
|
_longNames_FileIndex = fileIndex;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -686,7 +688,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
case kpidShortComment:
|
case kpidShortComment:
|
||||||
case kpidSubType:
|
case kpidSubType:
|
||||||
{
|
{
|
||||||
AString s = k_TypeExtionsions[(unsigned)_type];
|
AString s (k_TypeExtionsions[(unsigned)_type]);
|
||||||
if (_subType == kSubType_BSD)
|
if (_subType == kSubType_BSD)
|
||||||
s += ":BSD";
|
s += ":BSD";
|
||||||
prop = s;
|
prop = s;
|
||||||
@@ -718,7 +720,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
if (item.TextFileIndex >= 0)
|
if (item.TextFileIndex >= 0)
|
||||||
prop = (item.TextFileIndex == 0) ? "1.txt" : "2.txt";
|
prop = (item.TextFileIndex == 0) ? "1.txt" : "2.txt";
|
||||||
else
|
else
|
||||||
prop = (const wchar_t *)NItemName::GetOSName2(MultiByteToUnicodeString(item.Name, CP_OEMCP));
|
prop = (const wchar_t *)NItemName::GetOsPath_Remove_TailSlash(MultiByteToUnicodeString(item.Name, CP_OEMCP));
|
||||||
break;
|
break;
|
||||||
case kpidSize:
|
case kpidSize:
|
||||||
case kpidPackSize:
|
case kpidPackSize:
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
#include "../../../C/CpuArch.h"
|
#include "../../../C/CpuArch.h"
|
||||||
|
|
||||||
#include "../../Common/ComTry.h"
|
#include "../../Common/ComTry.h"
|
||||||
#include "../../Common/IntToString.h"
|
|
||||||
#include "../../Common/StringConvert.h"
|
#include "../../Common/StringConvert.h"
|
||||||
|
|
||||||
#include "../../Windows/PropVariant.h"
|
#include "../../Windows/PropVariant.h"
|
||||||
|
#include "../../Windows/PropVariantUtils.h"
|
||||||
#include "../../Windows/TimeUtils.h"
|
#include "../../Windows/TimeUtils.h"
|
||||||
|
|
||||||
#include "../Common/LimitedStreams.h"
|
#include "../Common/LimitedStreams.h"
|
||||||
@@ -642,16 +642,7 @@ static void SetTime(UInt32 dosTime, NCOM::CPropVariant &prop)
|
|||||||
|
|
||||||
static void SetHostOS(Byte hostOS, NCOM::CPropVariant &prop)
|
static void SetHostOS(Byte hostOS, NCOM::CPropVariant &prop)
|
||||||
{
|
{
|
||||||
char temp[16];
|
TYPE_TO_PROP(kHostOS, hostOS, prop);
|
||||||
const char *s = NULL;
|
|
||||||
if (hostOS < ARRAY_SIZE(kHostOS))
|
|
||||||
s = kHostOS[hostOS];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ConvertUInt32ToString(hostOS, temp);
|
|
||||||
s = temp;
|
|
||||||
}
|
|
||||||
prop = s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetUnicodeString(const AString &s, NCOM::CPropVariant &prop)
|
static void SetUnicodeString(const AString &s, NCOM::CPropVariant &prop)
|
||||||
@@ -703,7 +694,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
const CItem &item = _items[index];
|
const CItem &item = _items[index];
|
||||||
switch (propID)
|
switch (propID)
|
||||||
{
|
{
|
||||||
case kpidPath: prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break;
|
case kpidPath: prop = NItemName::GetOsPath(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break;
|
||||||
case kpidIsDir: prop = item.IsDir(); break;
|
case kpidIsDir: prop = item.IsDir(); break;
|
||||||
case kpidSize: prop = item.Size; break;
|
case kpidSize: prop = item.Size; break;
|
||||||
case kpidPackSize: prop = item.PackSize; break;
|
case kpidPackSize: prop = item.PackSize; break;
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ STDMETHODIMP CHandler::Close()
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
{
|
{
|
||||||
@@ -191,8 +192,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
if (_packSize_Defined)
|
if (_packSize_Defined)
|
||||||
extractCallback->SetTotal(_packSize);
|
extractCallback->SetTotal(_packSize);
|
||||||
|
|
||||||
// RINOK(extractCallback->SetCompleted(&packSize));
|
|
||||||
|
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
Int32 askMode = testMode ?
|
Int32 askMode = testMode ?
|
||||||
NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
@@ -203,7 +202,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
|
|
||||||
extractCallback->PrepareOperation(askMode);
|
extractCallback->PrepareOperation(askMode);
|
||||||
|
|
||||||
|
|
||||||
if (_needSeekToStart)
|
if (_needSeekToStart)
|
||||||
{
|
{
|
||||||
if (!_stream)
|
if (!_stream)
|
||||||
@@ -213,14 +211,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
else
|
else
|
||||||
_needSeekToStart = true;
|
_needSeekToStart = true;
|
||||||
|
|
||||||
Int32 opRes;
|
// try {
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
NCompress::NBZip2::CDecoder *decoderSpec = new NCompress::NBZip2::CDecoder;
|
NCompress::NBZip2::CDecoder *decoderSpec = new NCompress::NBZip2::CDecoder;
|
||||||
CMyComPtr<ICompressCoder> decoder = decoderSpec;
|
CMyComPtr<ICompressCoder> decoder = decoderSpec;
|
||||||
decoderSpec->SetInStream(_seqStream);
|
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
RINOK(decoderSpec->SetNumberOfThreads(_props._numThreads));
|
RINOK(decoderSpec->SetNumberOfThreads(_props._numThreads));
|
||||||
@@ -237,74 +231,43 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||||
lps->Init(extractCallback, true);
|
lps->Init(extractCallback, true);
|
||||||
|
|
||||||
UInt64 packSize = 0;
|
decoderSpec->FinishMode = true;
|
||||||
UInt64 unpackedSize = 0;
|
decoderSpec->Base.DecodeAllStreams = true;
|
||||||
UInt64 numStreams = 0;
|
|
||||||
|
|
||||||
decoderSpec->InitNumBlocks();
|
|
||||||
|
|
||||||
HRESULT result = S_OK;
|
_dataAfterEnd = false;
|
||||||
|
_needMoreInput = false;
|
||||||
|
|
||||||
for (;;)
|
lps->InSize = 0;
|
||||||
|
lps->OutSize = 0;
|
||||||
|
|
||||||
|
HRESULT result = decoderSpec->Code(_seqStream, outStream, NULL, NULL, progress);
|
||||||
|
|
||||||
|
if (result != S_FALSE && result != S_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (decoderSpec->Base.NumStreams == 0)
|
||||||
{
|
{
|
||||||
lps->InSize = packSize;
|
_isArc = false;
|
||||||
lps->OutSize = unpackedSize;
|
result = S_FALSE;
|
||||||
|
|
||||||
RINOK(lps->SetCur());
|
|
||||||
|
|
||||||
result = decoderSpec->CodeResume(outStream, progress);
|
|
||||||
|
|
||||||
if (result != S_FALSE && result != S_OK)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
if (decoderSpec->IsBz)
|
|
||||||
numStreams++;
|
|
||||||
else if (numStreams == 0)
|
|
||||||
{
|
|
||||||
_isArc = false;
|
|
||||||
result = S_FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
unpackedSize = outStreamSpec->GetSize();
|
|
||||||
UInt64 streamSize = decoderSpec->GetStreamSize();
|
|
||||||
|
|
||||||
if (streamSize == packSize)
|
|
||||||
{
|
|
||||||
// no new bytes in input stream, So it's good end of archive.
|
|
||||||
result = S_OK;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!decoderSpec->IsBz)
|
|
||||||
{
|
|
||||||
_dataAfterEnd = true;
|
|
||||||
result = S_FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decoderSpec->Base.BitDecoder.ExtraBitsWereRead())
|
|
||||||
{
|
|
||||||
_needMoreInput = true;
|
|
||||||
packSize = streamSize;
|
|
||||||
result = S_FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
packSize = decoderSpec->GetInputProcessedSize();
|
|
||||||
|
|
||||||
if (packSize > streamSize)
|
|
||||||
return E_FAIL;
|
|
||||||
|
|
||||||
if (result != S_OK)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (numStreams != 0)
|
|
||||||
{
|
{
|
||||||
|
const UInt64 inProcessedSize = decoderSpec->GetInputProcessedSize();
|
||||||
|
UInt64 packSize = inProcessedSize;
|
||||||
|
|
||||||
|
if (decoderSpec->Base.NeedMoreInput)
|
||||||
|
_needMoreInput = true;
|
||||||
|
|
||||||
|
if (!decoderSpec->Base.IsBz)
|
||||||
|
{
|
||||||
|
packSize = decoderSpec->Base.FinishedPackSize;
|
||||||
|
if (packSize != inProcessedSize)
|
||||||
|
_dataAfterEnd = true;
|
||||||
|
}
|
||||||
|
|
||||||
_packSize = packSize;
|
_packSize = packSize;
|
||||||
_unpackSize = unpackedSize;
|
_unpackSize = decoderSpec->GetOutProcessedSize();
|
||||||
_numStreams = numStreams;
|
_numStreams = decoderSpec->Base.NumStreams;
|
||||||
_numBlocks = decoderSpec->GetNumBlocks();
|
_numBlocks = decoderSpec->GetNumBlocks();
|
||||||
|
|
||||||
_packSize_Defined = true;
|
_packSize_Defined = true;
|
||||||
@@ -313,32 +276,36 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
_numBlocks_Defined = true;
|
_numBlocks_Defined = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
decoderSpec->ReleaseInStream();
|
|
||||||
outStream.Release();
|
outStream.Release();
|
||||||
|
|
||||||
|
Int32 opRes;
|
||||||
|
|
||||||
if (!_isArc)
|
if (!_isArc)
|
||||||
opRes = NExtract::NOperationResult::kIsNotArc;
|
opRes = NExtract::NOperationResult::kIsNotArc;
|
||||||
else if (_needMoreInput)
|
else if (_needMoreInput)
|
||||||
opRes = NExtract::NOperationResult::kUnexpectedEnd;
|
opRes = NExtract::NOperationResult::kUnexpectedEnd;
|
||||||
else if (decoderSpec->CrcError)
|
else if (decoderSpec->GetCrcError())
|
||||||
opRes = NExtract::NOperationResult::kCRCError;
|
opRes = NExtract::NOperationResult::kCRCError;
|
||||||
else if (_dataAfterEnd)
|
else if (_dataAfterEnd)
|
||||||
opRes = NExtract::NOperationResult::kDataAfterEnd;
|
opRes = NExtract::NOperationResult::kDataAfterEnd;
|
||||||
else if (result == S_FALSE)
|
else if (result == S_FALSE)
|
||||||
opRes = NExtract::NOperationResult::kDataError;
|
opRes = NExtract::NOperationResult::kDataError;
|
||||||
|
else if (decoderSpec->Base.MinorError)
|
||||||
|
opRes = NExtract::NOperationResult::kDataError;
|
||||||
else if (result == S_OK)
|
else if (result == S_OK)
|
||||||
opRes = NExtract::NOperationResult::kOK;
|
opRes = NExtract::NOperationResult::kOK;
|
||||||
else
|
else
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
|
||||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
|
||||||
|
|
||||||
return extractCallback->SetOperationResult(opRes);
|
return extractCallback->SetOperationResult(opRes);
|
||||||
|
|
||||||
|
// } catch(...) { return E_FAIL; }
|
||||||
|
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static HRESULT UpdateArchive(
|
static HRESULT UpdateArchive(
|
||||||
UInt64 unpackSize,
|
UInt64 unpackSize,
|
||||||
ISequentialOutStream *outStream,
|
ISequentialOutStream *outStream,
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
|
|
||||||
case kpidVolumeIndex:
|
case kpidVolumeIndex:
|
||||||
{
|
{
|
||||||
if (m_Database.Volumes.Size() == 1)
|
if (!m_Database.Volumes.IsEmpty())
|
||||||
{
|
{
|
||||||
const CDatabaseEx &db = m_Database.Volumes[0];
|
const CDatabaseEx &db = m_Database.Volumes[0];
|
||||||
const CInArcInfo &ai = db.ArcInfo;
|
const CInArcInfo &ai = db.ArcInfo;
|
||||||
@@ -226,12 +226,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
if (ai.SetID != 0)
|
if (ai.SetID != 0)
|
||||||
{
|
{
|
||||||
AString s;
|
AString s;
|
||||||
char temp[32];
|
s.Add_UInt32(ai.SetID);
|
||||||
ConvertUInt32ToString(ai.SetID, temp);
|
|
||||||
s += temp;
|
|
||||||
ConvertUInt32ToString(ai.CabinetNumber + 1, temp);
|
|
||||||
s += '_';
|
s += '_';
|
||||||
s += temp;
|
s.Add_UInt32(ai.CabinetNumber + 1);
|
||||||
s += ".cab";
|
s += ".cab";
|
||||||
prop = s;
|
prop = s;
|
||||||
}
|
}
|
||||||
@@ -288,7 +285,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
ConvertUTF8ToUnicode(item.Name, unicodeName);
|
ConvertUTF8ToUnicode(item.Name, unicodeName);
|
||||||
else
|
else
|
||||||
unicodeName = MultiByteToUnicodeString(item.Name, CP_ACP);
|
unicodeName = MultiByteToUnicodeString(item.Name, CP_ACP);
|
||||||
prop = (const wchar_t *)NItemName::WinNameToOSName(unicodeName);
|
prop = (const wchar_t *)NItemName::WinPathToOsPath(unicodeName);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,7 +488,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|||||||
|
|
||||||
if (!_errorMessage.IsEmpty())
|
if (!_errorMessage.IsEmpty())
|
||||||
_errorMessage.Add_LF();
|
_errorMessage.Add_LF();
|
||||||
_errorMessage.AddAscii("Can't open volume: ");
|
_errorMessage += "Can't open volume: ";
|
||||||
_errorMessage += fullName;
|
_errorMessage += fullName;
|
||||||
|
|
||||||
if (prevChecked)
|
if (prevChecked)
|
||||||
@@ -1017,11 +1014,11 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
for (; i < numItems; i++)
|
for (; i < numItems; i++)
|
||||||
{
|
{
|
||||||
unsigned indexNext = allFilesMode ? i : indices[i];
|
unsigned indexNext = allFilesMode ? i : indices[i];
|
||||||
const CMvItem &mvItem = m_Database.Items[indexNext];
|
const CMvItem &mvItem2 = m_Database.Items[indexNext];
|
||||||
const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
const CItem &item2 = m_Database.Volumes[mvItem2.VolumeIndex].Items[mvItem2.ItemIndex];
|
||||||
if (item.IsDir())
|
if (item2.IsDir())
|
||||||
continue;
|
continue;
|
||||||
int newFolderIndex = m_Database.GetFolderIndex(&mvItem);
|
int newFolderIndex = m_Database.GetFolderIndex(&mvItem2);
|
||||||
|
|
||||||
if (newFolderIndex != folderIndex)
|
if (newFolderIndex != folderIndex)
|
||||||
break;
|
break;
|
||||||
@@ -1029,7 +1026,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
extractStatuses.Add(false);
|
extractStatuses.Add(false);
|
||||||
extractStatuses.Add(true);
|
extractStatuses.Add(true);
|
||||||
startIndex++;
|
startIndex++;
|
||||||
curUnpack = item.GetEndOffset();
|
curUnpack = item2.GetEndOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
CFolderOutStream *cabFolderOutStream = new CFolderOutStream;
|
CFolderOutStream *cabFolderOutStream = new CFolderOutStream;
|
||||||
@@ -1104,16 +1101,16 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CDatabaseEx &db = m_Database.Volumes[volIndex];
|
const CDatabaseEx &db2 = m_Database.Volumes[volIndex];
|
||||||
const CFolder &folder = db.Folders[locFolderIndex];
|
const CFolder &folder2 = db2.Folders[locFolderIndex];
|
||||||
|
|
||||||
if (bl == 0)
|
if (bl == 0)
|
||||||
{
|
{
|
||||||
cabBlockInStreamSpec->ReservedSize = db.ArcInfo.GetDataBlockReserveSize();
|
cabBlockInStreamSpec->ReservedSize = db2.ArcInfo.GetDataBlockReserveSize();
|
||||||
RINOK(db.Stream->Seek(db.StartPosition + folder.DataStart, STREAM_SEEK_SET, NULL));
|
RINOK(db2.Stream->Seek(db2.StartPosition + folder2.DataStart, STREAM_SEEK_SET, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bl == folder.NumDataBlocks)
|
if (bl == folder2.NumDataBlocks)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
CFolder::NumDataBlocks (CFFOLDER::cCFData in CAB specification) is 16-bit.
|
CFolder::NumDataBlocks (CFFOLDER::cCFData in CAB specification) is 16-bit.
|
||||||
@@ -1138,7 +1135,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
cabBlockInStreamSpec->InitForNewBlock();
|
cabBlockInStreamSpec->InitForNewBlock();
|
||||||
|
|
||||||
UInt32 packSize, unpackSize;
|
UInt32 packSize, unpackSize;
|
||||||
res = cabBlockInStreamSpec->PreRead(db.Stream, packSize, unpackSize);
|
res = cabBlockInStreamSpec->PreRead(db2.Stream, packSize, unpackSize);
|
||||||
if (res == S_FALSE)
|
if (res == S_FALSE)
|
||||||
break;
|
break;
|
||||||
RINOK(res);
|
RINOK(res);
|
||||||
@@ -1180,7 +1177,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
UInt64 unpackSize64 = unpackSize;
|
UInt64 unpackSize64 = unpackSize;
|
||||||
UInt32 packSizeChunk = cabBlockInStreamSpec->GetPackSizeAvail();
|
UInt32 packSizeChunk = cabBlockInStreamSpec->GetPackSizeAvail();
|
||||||
|
|
||||||
switch (folder.GetMethod())
|
switch (folder2.GetMethod())
|
||||||
{
|
{
|
||||||
case NHeader::NMethod::kNone:
|
case NHeader::NMethod::kNone:
|
||||||
res = copyCoder->Code(cabBlockInStream, outStream, NULL, &unpackSize64, NULL);
|
res = copyCoder->Code(cabBlockInStream, outStream, NULL, &unpackSize64, NULL);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user