Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35596517f2 | ||
|
|
de4f8c22fe | ||
|
|
b75af1bba6 | ||
|
|
c65230d858 | ||
|
|
2eb60a0598 | ||
|
|
044e4bb741 | ||
|
|
e279500d76 | ||
|
|
708873490e |
@@ -1,7 +1,6 @@
|
|||||||
/* 7zAlloc.c -- Allocation functions
|
/* 7zAlloc.c -- Allocation functions
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
2010-10-29 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "7zAlloc.h"
|
#include "7zAlloc.h"
|
||||||
|
|
||||||
/* #define _SZ_ALLOC_DEBUG */
|
/* #define _SZ_ALLOC_DEBUG */
|
||||||
@@ -1,14 +1,10 @@
|
|||||||
/* 7zAlloc.h -- Allocation functions
|
/* 7zAlloc.h -- Allocation functions
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
2010-10-29 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_ALLOC_H
|
#ifndef __7Z_ALLOC_H
|
||||||
#define __7Z_ALLOC_H
|
#define __7Z_ALLOC_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *SzAlloc(void *p, size_t size);
|
void *SzAlloc(void *p, size_t size);
|
||||||
void SzFree(void *p, void *address);
|
void SzFree(void *p, void *address);
|
||||||
@@ -16,8 +12,4 @@ void SzFree(void *p, void *address);
|
|||||||
void *SzAllocTemp(void *p, size_t size);
|
void *SzAllocTemp(void *p, size_t size);
|
||||||
void SzFreeTemp(void *p, void *address);
|
void SzFreeTemp(void *p, void *address);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
65
C/7zCrc.c
@@ -1,15 +1,24 @@
|
|||||||
/* 7zCrc.c -- CRC32 calculation
|
/* 7zCrc.c -- CRC32 init
|
||||||
2009-11-23 : Igor Pavlov : Public domain */
|
2010-12-01 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "7zCrc.h"
|
#include "7zCrc.h"
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
|
||||||
#define kCrcPoly 0xEDB88320
|
#define kCrcPoly 0xEDB88320
|
||||||
|
|
||||||
#ifdef MY_CPU_LE
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
#define CRC_NUM_TABLES 8
|
#define CRC_NUM_TABLES 8
|
||||||
|
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||||
|
#elif defined(MY_CPU_LE)
|
||||||
|
#define CRC_NUM_TABLES 4
|
||||||
#else
|
#else
|
||||||
#define CRC_NUM_TABLES 1
|
#define CRC_NUM_TABLES 5
|
||||||
|
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
|
||||||
|
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MY_CPU_BE
|
||||||
|
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||||
@@ -17,25 +26,6 @@ typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size,
|
|||||||
static CRC_FUNC g_CrcUpdate;
|
static CRC_FUNC g_CrcUpdate;
|
||||||
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
|
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
|
||||||
|
|
||||||
#if CRC_NUM_TABLES == 1
|
|
||||||
|
|
||||||
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
|
||||||
|
|
||||||
static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
|
||||||
{
|
|
||||||
const Byte *p = (const Byte *)data;
|
|
||||||
for (; size > 0; size--, p++)
|
|
||||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
|
||||||
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
|
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
return g_CrcUpdate(v, data, size, g_CrcTable);
|
return g_CrcUpdate(v, data, size, g_CrcTable);
|
||||||
@@ -57,18 +47,37 @@ void MY_FAST_CALL CrcGenerateTable()
|
|||||||
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
||||||
g_CrcTable[i] = r;
|
g_CrcTable[i] = r;
|
||||||
}
|
}
|
||||||
#if CRC_NUM_TABLES == 1
|
|
||||||
g_CrcUpdate = CrcUpdateT1;
|
|
||||||
#else
|
|
||||||
for (; i < 256 * CRC_NUM_TABLES; i++)
|
for (; i < 256 * CRC_NUM_TABLES; i++)
|
||||||
{
|
{
|
||||||
UInt32 r = g_CrcTable[i - 256];
|
UInt32 r = g_CrcTable[i - 256];
|
||||||
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
|
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MY_CPU_LE
|
||||||
|
|
||||||
g_CrcUpdate = CrcUpdateT4;
|
g_CrcUpdate = CrcUpdateT4;
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
|
||||||
|
#if CRC_NUM_TABLES == 8
|
||||||
if (!CPU_Is_InOrder())
|
if (!CPU_Is_InOrder())
|
||||||
g_CrcUpdate = CrcUpdateT8;
|
g_CrcUpdate = CrcUpdateT8;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
#ifndef MY_CPU_BE
|
||||||
|
UInt32 k = 1;
|
||||||
|
if (*(const Byte *)&k == 1)
|
||||||
|
g_CrcUpdate = CrcUpdateT4;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
|
||||||
|
{
|
||||||
|
UInt32 x = g_CrcTable[i - 256];
|
||||||
|
g_CrcTable[i] = CRC_UINT32_SWAP(x);
|
||||||
|
}
|
||||||
|
g_CrcUpdate = CrcUpdateT1_BeT4;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
38
C/7zCrcOpt.c
@@ -1,12 +1,12 @@
|
|||||||
/* 7zCrcOpt.c -- CRC32 calculation : optimized version
|
/* 7zCrcOpt.c -- CRC32 calculation
|
||||||
2009-11-23 : Igor Pavlov : Public domain */
|
2010-12-01 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
|
||||||
#ifdef MY_CPU_LE
|
|
||||||
|
|
||||||
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||||
|
|
||||||
|
#ifndef MY_CPU_BE
|
||||||
|
|
||||||
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||||
{
|
{
|
||||||
const Byte *p = (const Byte *)data;
|
const Byte *p = (const Byte *)data;
|
||||||
@@ -32,3 +32,33 @@ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const U
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MY_CPU_LE
|
||||||
|
|
||||||
|
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
|
||||||
|
|
||||||
|
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||||
|
{
|
||||||
|
const Byte *p = (const Byte *)data;
|
||||||
|
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
|
||||||
|
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||||
|
v = CRC_UINT32_SWAP(v);
|
||||||
|
table += 0x100;
|
||||||
|
for (; size >= 4; size -= 4, p += 4)
|
||||||
|
{
|
||||||
|
v ^= *(const UInt32 *)p;
|
||||||
|
v =
|
||||||
|
table[0x000 + (v & 0xFF)] ^
|
||||||
|
table[0x100 + ((v >> 8) & 0xFF)] ^
|
||||||
|
table[0x200 + ((v >> 16) & 0xFF)] ^
|
||||||
|
table[0x300 + ((v >> 24))];
|
||||||
|
}
|
||||||
|
table -= 0x100;
|
||||||
|
v = CRC_UINT32_SWAP(v);
|
||||||
|
for (; size > 0; size--, p++)
|
||||||
|
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
60
C/7zDec.c
@@ -1,5 +1,5 @@
|
|||||||
/* 7zDec.c -- Decoding from 7z folder
|
/* 7zDec.c -- Decoding from 7z folder
|
||||||
2010-03-15 : Igor Pavlov : Public domain */
|
2010-11-02 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -18,9 +18,13 @@
|
|||||||
|
|
||||||
#define k_Copy 0
|
#define k_Copy 0
|
||||||
#define k_LZMA2 0x21
|
#define k_LZMA2 0x21
|
||||||
#define k_LZMA 0x30101
|
#define k_LZMA 0x30101
|
||||||
#define k_BCJ 0x03030103
|
#define k_BCJ 0x03030103
|
||||||
#define k_BCJ2 0x0303011B
|
#define k_PPC 0x03030205
|
||||||
|
#define k_ARM 0x03030501
|
||||||
|
#define k_ARMT 0x03030701
|
||||||
|
#define k_SPARC 0x03030805
|
||||||
|
#define k_BCJ2 0x0303011B
|
||||||
|
|
||||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||||
|
|
||||||
@@ -260,7 +264,6 @@ static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
|
|||||||
IS_MAIN_METHOD((UInt32)c->MethodID);
|
IS_MAIN_METHOD((UInt32)c->MethodID);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IS_BCJ(c) ((c)->MethodID == k_BCJ && (c)->NumInStreams == 1 && (c)->NumOutStreams == 1)
|
|
||||||
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
|
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
|
||||||
|
|
||||||
static SRes CheckSupportedFolder(const CSzFolder *f)
|
static SRes CheckSupportedFolder(const CSzFolder *f)
|
||||||
@@ -277,11 +280,24 @@ static SRes CheckSupportedFolder(const CSzFolder *f)
|
|||||||
}
|
}
|
||||||
if (f->NumCoders == 2)
|
if (f->NumCoders == 2)
|
||||||
{
|
{
|
||||||
if (!IS_BCJ(&f->Coders[1]) ||
|
CSzCoderInfo *c = &f->Coders[1];
|
||||||
f->NumPackStreams != 1 || f->PackStreams[0] != 0 ||
|
if (c->MethodID > (UInt32)0xFFFFFFFF ||
|
||||||
|
c->NumInStreams != 1 ||
|
||||||
|
c->NumOutStreams != 1 ||
|
||||||
|
f->NumPackStreams != 1 ||
|
||||||
|
f->PackStreams[0] != 0 ||
|
||||||
f->NumBindPairs != 1 ||
|
f->NumBindPairs != 1 ||
|
||||||
f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0)
|
f->BindPairs[0].InIndex != 1 ||
|
||||||
|
f->BindPairs[0].OutIndex != 0)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
switch ((UInt32)c->MethodID)
|
||||||
|
{
|
||||||
|
case k_BCJ:
|
||||||
|
case k_ARM:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
if (f->NumCoders == 4)
|
if (f->NumCoders == 4)
|
||||||
@@ -314,6 +330,8 @@ static UInt64 GetSum(const UInt64 *values, UInt32 index)
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
|
||||||
|
|
||||||
static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
|
static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
|
||||||
ILookInStream *inStream, UInt64 startPos,
|
ILookInStream *inStream, UInt64 startPos,
|
||||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
|
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
|
||||||
@@ -391,14 +409,6 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (coder->MethodID == k_BCJ)
|
|
||||||
{
|
|
||||||
UInt32 state;
|
|
||||||
if (ci != 1)
|
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
|
||||||
x86_Convert_Init(state);
|
|
||||||
x86_Convert(outBuffer, outSize, 0, &state, 0);
|
|
||||||
}
|
|
||||||
else if (coder->MethodID == k_BCJ2)
|
else if (coder->MethodID == k_BCJ2)
|
||||||
{
|
{
|
||||||
UInt64 offset = GetSum(packSizes, 1);
|
UInt64 offset = GetSum(packSizes, 1);
|
||||||
@@ -425,7 +435,23 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
|
|||||||
RINOK(res)
|
RINOK(res)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
{
|
||||||
|
if (ci != 1)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
switch(coder->MethodID)
|
||||||
|
{
|
||||||
|
case k_BCJ:
|
||||||
|
{
|
||||||
|
UInt32 state;
|
||||||
|
x86_Convert_Init(state);
|
||||||
|
x86_Convert(outBuffer, outSize, 0, &state, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
CASE_BRA_CONV(ARM)
|
||||||
|
default:
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
16
C/7zIn.c
@@ -1,5 +1,5 @@
|
|||||||
/* 7zIn.c -- 7z Input functions
|
/* 7zIn.c -- 7z Input functions
|
||||||
2010-03-11 : Igor Pavlov : Public domain */
|
2010-10-29 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -1218,12 +1218,16 @@ static SRes SzArEx_Open2(
|
|||||||
ISzAlloc *allocTemp)
|
ISzAlloc *allocTemp)
|
||||||
{
|
{
|
||||||
Byte header[k7zStartHeaderSize];
|
Byte header[k7zStartHeaderSize];
|
||||||
|
Int64 startArcPos;
|
||||||
UInt64 nextHeaderOffset, nextHeaderSize;
|
UInt64 nextHeaderOffset, nextHeaderSize;
|
||||||
size_t nextHeaderSizeT;
|
size_t nextHeaderSizeT;
|
||||||
UInt32 nextHeaderCRC;
|
UInt32 nextHeaderCRC;
|
||||||
CBuf buffer;
|
CBuf buffer;
|
||||||
SRes res;
|
SRes res;
|
||||||
|
|
||||||
|
startArcPos = 0;
|
||||||
|
RINOK(inStream->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));
|
||||||
|
|
||||||
if (!TestSignatureCandidate(header))
|
if (!TestSignatureCandidate(header))
|
||||||
@@ -1235,7 +1239,7 @@ static SRes SzArEx_Open2(
|
|||||||
nextHeaderSize = GetUi64(header + 20);
|
nextHeaderSize = GetUi64(header + 20);
|
||||||
nextHeaderCRC = GetUi32(header + 28);
|
nextHeaderCRC = GetUi32(header + 28);
|
||||||
|
|
||||||
p->startPosAfterHeader = k7zStartHeaderSize;
|
p->startPosAfterHeader = startArcPos + k7zStartHeaderSize;
|
||||||
|
|
||||||
if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
|
if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
|
||||||
return SZ_ERROR_CRC;
|
return SZ_ERROR_CRC;
|
||||||
@@ -1252,13 +1256,13 @@ static SRes SzArEx_Open2(
|
|||||||
{
|
{
|
||||||
Int64 pos = 0;
|
Int64 pos = 0;
|
||||||
RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
|
RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
|
||||||
if ((UInt64)pos < nextHeaderOffset ||
|
if ((UInt64)pos < startArcPos + nextHeaderOffset ||
|
||||||
(UInt64)pos < k7zStartHeaderSize + nextHeaderOffset ||
|
(UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
|
||||||
(UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
|
(UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
|
||||||
return SZ_ERROR_INPUT_EOF;
|
return SZ_ERROR_INPUT_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset));
|
RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset));
|
||||||
|
|
||||||
if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
|
if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#define MY_VER_MAJOR 9
|
#define MY_VER_MAJOR 9
|
||||||
#define MY_VER_MINOR 13
|
#define MY_VER_MINOR 21
|
||||||
#define MY_VER_BUILD 0
|
#define MY_VER_BUILD 00
|
||||||
#define MY_VERSION "9.13 beta"
|
#define MY_VERSION "9.21 beta"
|
||||||
#define MY_DATE "2010-04-15"
|
#define MY_DATE "2011-04-11"
|
||||||
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
|
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
|
||||||
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
|
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
|
||||||
|
|||||||
6
C/Bra.c
@@ -1,5 +1,5 @@
|
|||||||
/* Bra.c -- Converters for RISC code
|
/* Bra.c -- Converters for RISC code
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
2010-04-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Bra.h"
|
#include "Bra.h"
|
||||||
|
|
||||||
@@ -104,8 +104,8 @@ SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
|||||||
size -= 4;
|
size -= 4;
|
||||||
for (i = 0; i <= size; i += 4)
|
for (i = 0; i <= size; i += 4)
|
||||||
{
|
{
|
||||||
if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 ||
|
if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
|
||||||
data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)
|
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
|
||||||
{
|
{
|
||||||
UInt32 src =
|
UInt32 src =
|
||||||
((UInt32)data[i + 0] << 24) |
|
((UInt32)data[i + 0] << 24) |
|
||||||
|
|||||||
16
C/CpuArch.c
@@ -1,5 +1,5 @@
|
|||||||
/* CpuArch.c -- CPU specific code
|
/* CpuArch.c -- CPU specific code
|
||||||
2009-12-12: Igor Pavlov : Public domain */
|
2010-10-26: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
|
||||||
@@ -72,13 +72,13 @@ static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
"cpuid"
|
"cpuid"
|
||||||
: "=a" (*a) ,
|
: "=a" (*a) ,
|
||||||
"=b" (*b) ,
|
"=b" (*b) ,
|
||||||
"=c" (*c) ,
|
"=c" (*c) ,
|
||||||
"=d" (*d)
|
"=d" (*d)
|
||||||
: "0" (function)) ;
|
: "0" (function)) ;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
21
C/CpuArch.h
@@ -1,5 +1,5 @@
|
|||||||
/* CpuArch.h -- CPU specific code
|
/* CpuArch.h -- CPU specific code
|
||||||
2010-03-11: Igor Pavlov : Public domain */
|
2010-12-01: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __CPU_ARCH_H
|
#ifndef __CPU_ARCH_H
|
||||||
#define __CPU_ARCH_H
|
#define __CPU_ARCH_H
|
||||||
@@ -40,14 +40,26 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
|
|||||||
#define MY_CPU_ARM_LE
|
#define MY_CPU_ARM_LE
|
||||||
#endif
|
#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)
|
||||||
#define MY_CPU_LE_UNALIGN
|
#define MY_CPU_LE_UNALIGN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE)
|
#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
|
||||||
#define MY_CPU_LE
|
#define MY_CPU_LE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__)
|
||||||
|
#define MY_CPU_BE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
|
||||||
|
Stop_Compiling_Bad_Endian
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MY_CPU_LE_UNALIGN
|
#ifdef MY_CPU_LE_UNALIGN
|
||||||
|
|
||||||
#define GetUi16(p) (*(const UInt16 *)(p))
|
#define GetUi16(p) (*(const UInt16 *)(p))
|
||||||
@@ -55,6 +67,7 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
|
|||||||
#define GetUi64(p) (*(const UInt64 *)(p))
|
#define GetUi64(p) (*(const UInt64 *)(p))
|
||||||
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
|
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
|
||||||
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
|
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
|
||||||
|
#define SetUi64(p, d) *(UInt64 *)(p) = (d);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -78,6 +91,10 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
|
|||||||
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
|
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
|
||||||
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
|
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
|
||||||
|
|
||||||
|
#define SetUi64(p, d) { UInt64 _x64_ = (d); \
|
||||||
|
SetUi32(p, (UInt32)_x64_); \
|
||||||
|
SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
|
#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
|
||||||
|
|||||||
26
C/Lzma2Dec.c
@@ -1,5 +1,5 @@
|
|||||||
/* Lzma2Dec.c -- LZMA2 Decoder
|
/* Lzma2Dec.c -- LZMA2 Decoder
|
||||||
2009-05-03 : Igor Pavlov : Public domain */
|
2010-12-15 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
/* #define SHOW_DEBUG_INFO */
|
/* #define SHOW_DEBUG_INFO */
|
||||||
|
|
||||||
@@ -330,27 +330,21 @@ SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *
|
|||||||
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, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
CLzma2Dec decoder;
|
CLzma2Dec p;
|
||||||
SRes res;
|
SRes res;
|
||||||
SizeT outSize = *destLen, inSize = *srcLen;
|
SizeT outSize = *destLen, inSize = *srcLen;
|
||||||
Byte props[LZMA_PROPS_SIZE];
|
|
||||||
|
|
||||||
Lzma2Dec_Construct(&decoder);
|
|
||||||
|
|
||||||
*destLen = *srcLen = 0;
|
*destLen = *srcLen = 0;
|
||||||
*status = LZMA_STATUS_NOT_SPECIFIED;
|
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||||
decoder.decoder.dic = dest;
|
Lzma2Dec_Construct(&p);
|
||||||
decoder.decoder.dicBufSize = outSize;
|
RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
|
||||||
|
p.decoder.dic = dest;
|
||||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
p.decoder.dicBufSize = outSize;
|
||||||
RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc));
|
Lzma2Dec_Init(&p);
|
||||||
|
|
||||||
*srcLen = inSize;
|
*srcLen = inSize;
|
||||||
res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status);
|
res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
|
||||||
*destLen = decoder.decoder.dicPos;
|
*destLen = p.decoder.dicPos;
|
||||||
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||||
res = SZ_ERROR_INPUT_EOF;
|
res = SZ_ERROR_INPUT_EOF;
|
||||||
|
Lzma2Dec_FreeProbs(&p, alloc);
|
||||||
LzmaDec_FreeProbs(&decoder.decoder, alloc);
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Lzma2Enc.c -- LZMA2 Encoder
|
/* Lzma2Enc.c -- LZMA2 Encoder
|
||||||
2010-03-25 : Igor Pavlov : Public domain */
|
2010-09-24 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
/* #include <stdio.h> */
|
/* #include <stdio.h> */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -141,7 +141,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
|||||||
|
|
||||||
PRF(printf(" "));
|
PRF(printf(" "));
|
||||||
|
|
||||||
outBuf[destPos++] = (Byte)(LZMA2_CONTROL_LZMA | (mode << 5) | (u >> 16) & 0x1F);
|
outBuf[destPos++] = (Byte)(LZMA2_CONTROL_LZMA | (mode << 5) | ((u >> 16) & 0x1F));
|
||||||
outBuf[destPos++] = (Byte)(u >> 8);
|
outBuf[destPos++] = (Byte)(u >> 8);
|
||||||
outBuf[destPos++] = (Byte)u;
|
outBuf[destPos++] = (Byte)u;
|
||||||
outBuf[destPos++] = (Byte)(pm >> 8);
|
outBuf[destPos++] = (Byte)(pm >> 8);
|
||||||
@@ -269,7 +269,7 @@ static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
|
|||||||
|
|
||||||
if (mainEncoder->outBuf == 0)
|
if (mainEncoder->outBuf == 0)
|
||||||
{
|
{
|
||||||
mainEncoder->outBuf = IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
|
mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
|
||||||
if (mainEncoder->outBuf == 0)
|
if (mainEncoder->outBuf == 0)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
}
|
}
|
||||||
|
|||||||
22
C/LzmaDec.c
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaDec.c -- LZMA Decoder
|
/* LzmaDec.c -- LZMA Decoder
|
||||||
2009-09-20 : Igor Pavlov : Public domain */
|
2010-12-15 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "LzmaDec.h"
|
#include "LzmaDec.h"
|
||||||
|
|
||||||
@@ -442,8 +442,9 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
|
|||||||
|
|
||||||
p->processedPos += len;
|
p->processedPos += len;
|
||||||
p->remainLen -= len;
|
p->remainLen -= len;
|
||||||
while (len-- != 0)
|
while (len != 0)
|
||||||
{
|
{
|
||||||
|
len--;
|
||||||
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
||||||
dicPos++;
|
dicPos++;
|
||||||
}
|
}
|
||||||
@@ -972,28 +973,21 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
|||||||
{
|
{
|
||||||
CLzmaDec p;
|
CLzmaDec p;
|
||||||
SRes res;
|
SRes res;
|
||||||
SizeT inSize = *srcLen;
|
SizeT outSize = *destLen, inSize = *srcLen;
|
||||||
SizeT outSize = *destLen;
|
*destLen = *srcLen = 0;
|
||||||
*srcLen = *destLen = 0;
|
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||||
if (inSize < RC_INIT_SIZE)
|
if (inSize < RC_INIT_SIZE)
|
||||||
return SZ_ERROR_INPUT_EOF;
|
return SZ_ERROR_INPUT_EOF;
|
||||||
|
|
||||||
LzmaDec_Construct(&p);
|
LzmaDec_Construct(&p);
|
||||||
res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
|
RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc));
|
||||||
if (res != 0)
|
|
||||||
return res;
|
|
||||||
p.dic = dest;
|
p.dic = dest;
|
||||||
p.dicBufSize = outSize;
|
p.dicBufSize = outSize;
|
||||||
|
|
||||||
LzmaDec_Init(&p);
|
LzmaDec_Init(&p);
|
||||||
|
|
||||||
*srcLen = inSize;
|
*srcLen = inSize;
|
||||||
res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
|
res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
|
||||||
|
*destLen = p.dicPos;
|
||||||
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||||
res = SZ_ERROR_INPUT_EOF;
|
res = SZ_ERROR_INPUT_EOF;
|
||||||
|
|
||||||
(*destLen) = p.dicPos;
|
|
||||||
LzmaDec_FreeProbs(&p, alloc);
|
LzmaDec_FreeProbs(&p, alloc);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
16
C/LzmaEnc.c
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaEnc.c -- LZMA Encoder
|
/* LzmaEnc.c -- LZMA Encoder
|
||||||
2009-11-24 : Igor Pavlov : Public domain */
|
2011-01-27 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -46,6 +46,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p)
|
|||||||
{
|
{
|
||||||
p->level = 5;
|
p->level = 5;
|
||||||
p->dictSize = p->mc = 0;
|
p->dictSize = p->mc = 0;
|
||||||
|
p->reduceSize = (UInt32)(Int32)-1;
|
||||||
p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
|
p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
|
||||||
p->writeEndMark = 0;
|
p->writeEndMark = 0;
|
||||||
}
|
}
|
||||||
@@ -56,6 +57,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 == 6 ? (1 << 25) : (1 << 26)));
|
||||||
|
if (p->dictSize > p->reduceSize)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 15; i <= 30; i++)
|
||||||
|
{
|
||||||
|
if (p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
|
||||||
|
if (p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
if (p->lc < 0) p->lc = 3;
|
if (p->lc < 0) p->lc = 3;
|
||||||
if (p->lp < 0) p->lp = 0;
|
if (p->lp < 0) p->lp = 0;
|
||||||
if (p->pb < 0) p->pb = 2;
|
if (p->pb < 0) p->pb = 2;
|
||||||
@@ -329,7 +339,6 @@ typedef struct
|
|||||||
|
|
||||||
SRes result;
|
SRes result;
|
||||||
UInt32 dictSize;
|
UInt32 dictSize;
|
||||||
UInt32 matchFinderCycles;
|
|
||||||
|
|
||||||
int needInit;
|
int needInit;
|
||||||
|
|
||||||
@@ -395,10 +404,9 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
|
|||||||
LzmaEncProps_Normalize(&props);
|
LzmaEncProps_Normalize(&props);
|
||||||
|
|
||||||
if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
|
if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
|
||||||
props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30))
|
props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30))
|
||||||
return SZ_ERROR_PARAM;
|
return SZ_ERROR_PARAM;
|
||||||
p->dictSize = props.dictSize;
|
p->dictSize = props.dictSize;
|
||||||
p->matchFinderCycles = props.mc;
|
|
||||||
{
|
{
|
||||||
unsigned fb = props.fb;
|
unsigned fb = props.fb;
|
||||||
if (fb < 5)
|
if (fb < 5)
|
||||||
|
|||||||
12
C/LzmaEnc.h
@@ -1,14 +1,12 @@
|
|||||||
/* LzmaEnc.h -- LZMA Encoder
|
/* LzmaEnc.h -- LZMA Encoder
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
2011-01-27 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZMA_ENC_H
|
#ifndef __LZMA_ENC_H
|
||||||
#define __LZMA_ENC_H
|
#define __LZMA_ENC_H
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_BEGIN
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LZMA_PROPS_SIZE 5
|
#define LZMA_PROPS_SIZE 5
|
||||||
|
|
||||||
@@ -18,6 +16,8 @@ typedef struct _CLzmaEncProps
|
|||||||
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 <= (1 << 30) for 64-bit version
|
||||||
default = (1 << 24) */
|
default = (1 << 24) */
|
||||||
|
UInt32 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 */
|
||||||
@@ -73,8 +73,6 @@ 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, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_END
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* MtCoder.c -- Multi-thread Coder
|
/* MtCoder.c -- Multi-thread Coder
|
||||||
2010-03-24 : Igor Pavlov : Public domain */
|
2010-09-24 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ static void CMtThread_Destruct(CMtThread *p)
|
|||||||
#define MY_BUF_ALLOC(buf, size, newSize) \
|
#define MY_BUF_ALLOC(buf, size, newSize) \
|
||||||
if (buf == 0 || size != newSize) \
|
if (buf == 0 || size != newSize) \
|
||||||
{ IAlloc_Free(p->mtCoder->alloc, buf); \
|
{ IAlloc_Free(p->mtCoder->alloc, buf); \
|
||||||
size = newSize; buf = IAlloc_Alloc(p->mtCoder->alloc, size); \
|
size = newSize; buf = (Byte *)IAlloc_Alloc(p->mtCoder->alloc, size); \
|
||||||
if (buf == 0) return SZ_ERROR_MEM; }
|
if (buf == 0) return SZ_ERROR_MEM; }
|
||||||
|
|
||||||
static SRes CMtThread_Prepare(CMtThread *p)
|
static SRes CMtThread_Prepare(CMtThread *p)
|
||||||
|
|||||||
7
C/Ppmd.h
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd.h -- PPMD codec common code
|
/* Ppmd.h -- PPMD codec common code
|
||||||
2010-03-12 : Igor Pavlov : Public domain
|
2011-01-27 : 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
|
||||||
@@ -29,6 +29,9 @@ EXTERN_C_BEGIN
|
|||||||
#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
|
#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
|
||||||
#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
|
#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
/* Most compilers works OK here even without #pragma pack(push, 1), but some GCC compilers need it. */
|
||||||
|
|
||||||
/* SEE-contexts for PPM-contexts with masked symbols */
|
/* SEE-contexts for PPM-contexts with masked symbols */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -48,6 +51,8 @@ typedef struct
|
|||||||
UInt16 SuccessorHigh;
|
UInt16 SuccessorHigh;
|
||||||
} CPpmd_State;
|
} CPpmd_State;
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
#ifdef PPMD_32BIT
|
#ifdef PPMD_32BIT
|
||||||
CPpmd_State *
|
CPpmd_State *
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd8.h -- PPMdI codec
|
/* Ppmd8.h -- PPMdI codec
|
||||||
2010-03-24 : Igor Pavlov : Public domain
|
2011-01-27 : 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 */
|
||||||
@@ -24,6 +24,8 @@ typedef
|
|||||||
#endif
|
#endif
|
||||||
CPpmd8_Context_Ref;
|
CPpmd8_Context_Ref;
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
typedef struct CPpmd8_Context_
|
typedef struct CPpmd8_Context_
|
||||||
{
|
{
|
||||||
Byte NumStats;
|
Byte NumStats;
|
||||||
@@ -33,6 +35,8 @@ typedef struct CPpmd8_Context_
|
|||||||
CPpmd8_Context_Ref Suffix;
|
CPpmd8_Context_Ref Suffix;
|
||||||
} CPpmd8_Context;
|
} CPpmd8_Context;
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
#define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
|
#define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
|
||||||
|
|
||||||
/* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed
|
/* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd8Dec.c -- PPMdI Decoder
|
/* Ppmd8Dec.c -- PPMdI Decoder
|
||||||
2010-03-12 : Igor Pavlov : Public domain
|
2010-04-16 : 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 */
|
||||||
@@ -33,7 +33,7 @@ static void RangeDec_Decode(CPpmd8 *p, UInt32 start, UInt32 size)
|
|||||||
p->Range *= size;
|
p->Range *= 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) | p->Stream.In->Read(p->Stream.In);
|
||||||
p->Range <<= 8;
|
p->Range <<= 8;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Ppmd8Enc.c -- PPMdI Encoder
|
/* Ppmd8Enc.c -- PPMdI Encoder
|
||||||
2010-03-12 : Igor Pavlov : Public domain
|
2010-04-16 : 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 */
|
||||||
@@ -19,7 +19,7 @@ void Ppmd8_RangeEnc_FlushData(CPpmd8 *p)
|
|||||||
static void RangeEnc_Normalize(CPpmd8 *p)
|
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));
|
p->Stream.Out->Write(p->Stream.Out, (Byte)(p->Low >> 24));
|
||||||
p->Range <<= 8;
|
p->Range <<= 8;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/* Crypto/Sha256.c -- SHA-256 Hash function
|
/* Crypto/Sha256.c -- SHA-256 Hash
|
||||||
2008-11-06 : Igor Pavlov : Public domain
|
2010-06-11 : 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 "Sha256.h"
|
|
||||||
#include "RotateDefs.h"
|
#include "RotateDefs.h"
|
||||||
|
#include "Sha256.h"
|
||||||
|
|
||||||
/* define it for speed optimization */
|
/* define it for speed optimization */
|
||||||
/* #define _SHA256_UNROLL */
|
/* #define _SHA256_UNROLL */
|
||||||
@@ -71,7 +71,7 @@ void Sha256_Init(CSha256 *p)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const UInt32 K[64] = {
|
static const UInt32 K[64] = {
|
||||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||||
|
|||||||
10
C/Sha256.h
@@ -1,14 +1,12 @@
|
|||||||
/* Sha256.h -- SHA-256 Hash
|
/* Sha256.h -- SHA-256 Hash
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
2010-06-11 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __CRYPTO_SHA256_H
|
#ifndef __CRYPTO_SHA256_H
|
||||||
#define __CRYPTO_SHA256_H
|
#define __CRYPTO_SHA256_H
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_BEGIN
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SHA256_DIGEST_SIZE 32
|
#define SHA256_DIGEST_SIZE 32
|
||||||
|
|
||||||
@@ -23,8 +21,6 @@ void Sha256_Init(CSha256 *p);
|
|||||||
void Sha256_Update(CSha256 *p, const Byte *data, size_t size);
|
void Sha256_Update(CSha256 *p, const Byte *data, size_t size);
|
||||||
void Sha256_Final(CSha256 *p, Byte *digest);
|
void Sha256_Final(CSha256 *p, Byte *digest);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_END
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
6
C/Sort.c
@@ -1,7 +1,5 @@
|
|||||||
/* Sort.c -- Sort functions
|
/* Sort.c -- Sort functions
|
||||||
2008-08-17
|
2010-09-17 : Igor Pavlov : Public domain */
|
||||||
Igor Pavlov
|
|
||||||
Public domain */
|
|
||||||
|
|
||||||
#include "Sort.h"
|
#include "Sort.h"
|
||||||
|
|
||||||
@@ -92,4 +90,4 @@ void HeapSortRef(UInt32 *p, UInt32 *vals, UInt32 size)
|
|||||||
}
|
}
|
||||||
while (size > 1);
|
while (size > 1);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|||||||
20
C/Types.h
@@ -1,5 +1,5 @@
|
|||||||
/* Types.h -- Basic types
|
/* Types.h -- Basic types
|
||||||
2010-03-11 : Igor Pavlov : Public domain */
|
2010-10-09 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_TYPES_H
|
#ifndef __7Z_TYPES_H
|
||||||
#define __7Z_TYPES_H
|
#define __7Z_TYPES_H
|
||||||
@@ -77,9 +77,11 @@ typedef unsigned long UInt64;
|
|||||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||||
typedef __int64 Int64;
|
typedef __int64 Int64;
|
||||||
typedef unsigned __int64 UInt64;
|
typedef unsigned __int64 UInt64;
|
||||||
|
#define UINT64_CONST(n) n
|
||||||
#else
|
#else
|
||||||
typedef long long int Int64;
|
typedef long long int Int64;
|
||||||
typedef unsigned long long int UInt64;
|
typedef unsigned long long int UInt64;
|
||||||
|
#define UINT64_CONST(n) n ## ULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -231,6 +233,22 @@ typedef struct
|
|||||||
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
||||||
#define IAlloc_Free(p, a) (p)->Free((p), a)
|
#define IAlloc_Free(p, a) (p)->Free((p), a)
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#define CHAR_PATH_SEPARATOR '\\'
|
||||||
|
#define WCHAR_PATH_SEPARATOR L'\\'
|
||||||
|
#define STRING_PATH_SEPARATOR "\\"
|
||||||
|
#define WSTRING_PATH_SEPARATOR L"\\"
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define CHAR_PATH_SEPARATOR '/'
|
||||||
|
#define WCHAR_PATH_SEPARATOR L'/'
|
||||||
|
#define STRING_PATH_SEPARATOR "/"
|
||||||
|
#define WSTRING_PATH_SEPARATOR L"/"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -92,6 +92,14 @@ SOURCE=..\..\7z.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7zAlloc.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7zAlloc.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\7zBuf.c
|
SOURCE=..\..\7zBuf.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -141,6 +149,10 @@ SOURCE=..\..\Bcj2.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Bra.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\Bra.h
|
SOURCE=..\..\Bra.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -196,14 +208,6 @@ SOURCE=..\..\Types.h
|
|||||||
# End Group
|
# End Group
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\7zAlloc.c
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\7zAlloc.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\7zMain.c
|
SOURCE=.\7zMain.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Target
|
# End Target
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
/* 7zMain.c - Test application for 7z Decoder
|
/* 7zMain.c - Test application for 7z Decoder
|
||||||
2010-03-12 : Igor Pavlov : Public domain */
|
2010-10-28 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../../7z.h"
|
#include "../../7z.h"
|
||||||
|
#include "../../7zAlloc.h"
|
||||||
#include "../../7zCrc.h"
|
#include "../../7zCrc.h"
|
||||||
#include "../../7zFile.h"
|
#include "../../7zFile.h"
|
||||||
#include "../../7zVersion.h"
|
#include "../../7zVersion.h"
|
||||||
|
|
||||||
#include "7zAlloc.h"
|
|
||||||
|
|
||||||
#ifndef USE_WINDOWS_FILE
|
#ifndef USE_WINDOWS_FILE
|
||||||
/* for mkdir */
|
/* for mkdir */
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -21,12 +20,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define CHAR_PATH_SEPARATOR '\\'
|
|
||||||
#else
|
|
||||||
#define CHAR_PATH_SEPARATOR '/'
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
||||||
|
|
||||||
static int Buf_EnsureSize(CBuf *dest, size_t size)
|
static int Buf_EnsureSize(CBuf *dest, size_t size)
|
||||||
@@ -104,7 +97,7 @@ static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static WRes Utf16_To_Char(CBuf *buf, const UInt16 *s, int fileMode)
|
static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s, int fileMode)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
for (len = 0; s[len] != '\0'; len++);
|
for (len = 0; s[len] != '\0'; len++);
|
||||||
@@ -117,7 +110,14 @@ static WRes Utf16_To_Char(CBuf *buf, const UInt16 *s, int fileMode)
|
|||||||
{
|
{
|
||||||
char defaultChar = '_';
|
char defaultChar = '_';
|
||||||
BOOL defUsed;
|
BOOL defUsed;
|
||||||
int numChars = WideCharToMultiByte(fileMode ? (AreFileApisANSI() ? CP_ACP : CP_OEMCP) : CP_OEMCP,
|
int numChars = WideCharToMultiByte(fileMode ?
|
||||||
|
(
|
||||||
|
#ifdef UNDER_CE
|
||||||
|
CP_ACP
|
||||||
|
#else
|
||||||
|
AreFileApisANSI() ? CP_ACP : CP_OEMCP
|
||||||
|
#endif
|
||||||
|
) : CP_OEMCP,
|
||||||
0, s, len, (char *)buf->data, size, &defaultChar, &defUsed);
|
0, s, len, (char *)buf->data, size, &defaultChar, &defUsed);
|
||||||
if (numChars == 0 || numChars >= size)
|
if (numChars == 0 || numChars >= size)
|
||||||
return SZ_ERROR_FAIL;
|
return SZ_ERROR_FAIL;
|
||||||
@@ -172,15 +172,16 @@ static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PrintString(const UInt16 *s)
|
static SRes PrintString(const UInt16 *s)
|
||||||
{
|
{
|
||||||
CBuf buf;
|
CBuf buf;
|
||||||
|
SRes res;
|
||||||
Buf_Init(&buf);
|
Buf_Init(&buf);
|
||||||
if (Utf16_To_Char(&buf, s, 0) == 0)
|
res = Utf16_To_Char(&buf, s, 0);
|
||||||
{
|
if (res == SZ_OK)
|
||||||
printf("%s", buf.data);
|
fputs((const char *)buf.data, stdout);
|
||||||
Buf_Free(&buf, &g_Alloc);
|
Buf_Free(&buf, &g_Alloc);
|
||||||
}
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UInt64ToStr(UInt64 value, char *s)
|
static void UInt64ToStr(UInt64 value, char *s)
|
||||||
@@ -398,16 +399,21 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("%s %s %10s ", t, attr, s);
|
printf("%s %s %10s ", t, attr, s);
|
||||||
PrintString(temp);
|
res = PrintString(temp);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
break;
|
||||||
if (f->IsDir)
|
if (f->IsDir)
|
||||||
printf("/");
|
printf("/");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
printf(testCommand ?
|
fputs(testCommand ?
|
||||||
"Testing ":
|
"Testing ":
|
||||||
"Extracting ");
|
"Extracting ",
|
||||||
PrintString(temp);
|
stdout);
|
||||||
|
res = PrintString(temp);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
break;
|
||||||
if (f->IsDir)
|
if (f->IsDir)
|
||||||
printf("/");
|
printf("/");
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT
|
|||||||
PROG = 7zDec.exe
|
PROG = 7zDec.exe
|
||||||
|
|
||||||
C_OBJS = \
|
C_OBJS = \
|
||||||
|
$O\7zAlloc.obj \
|
||||||
$O\7zBuf.obj \
|
$O\7zBuf.obj \
|
||||||
$O\7zBuf2.obj \
|
$O\7zBuf2.obj \
|
||||||
$O\7zCrc.obj \
|
$O\7zCrc.obj \
|
||||||
@@ -13,6 +14,7 @@ C_OBJS = \
|
|||||||
$O\7zIn.obj \
|
$O\7zIn.obj \
|
||||||
$O\7zStream.obj \
|
$O\7zStream.obj \
|
||||||
$O\Bcj2.obj \
|
$O\Bcj2.obj \
|
||||||
|
$O\Bra.obj \
|
||||||
$O\Bra86.obj \
|
$O\Bra86.obj \
|
||||||
$O\CpuArch.obj \
|
$O\CpuArch.obj \
|
||||||
$O\Lzma2Dec.obj \
|
$O\Lzma2Dec.obj \
|
||||||
@@ -21,7 +23,6 @@ C_OBJS = \
|
|||||||
$O\Ppmd7Dec.obj \
|
$O\Ppmd7Dec.obj \
|
||||||
|
|
||||||
7Z_OBJS = \
|
7Z_OBJS = \
|
||||||
$O\7zAlloc.obj \
|
|
||||||
$O\7zMain.obj \
|
$O\7zMain.obj \
|
||||||
|
|
||||||
OBJS = \
|
OBJS = \
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ LIB =
|
|||||||
RM = rm -f
|
RM = rm -f
|
||||||
CFLAGS = -c -O2 -Wall
|
CFLAGS = -c -O2 -Wall
|
||||||
|
|
||||||
OBJS = 7zMain.o 7zAlloc.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o 7zIn.o CpuArch.o LzmaDec.o Lzma2Dec.o Bra86.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o
|
OBJS = 7zMain.o 7zAlloc.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o 7zIn.o CpuArch.o LzmaDec.o Lzma2Dec.o Bra.o Bra86.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o
|
||||||
|
|
||||||
all: $(PROG)
|
all: $(PROG)
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ $(PROG): $(OBJS)
|
|||||||
$(CXX) $(CFLAGS) 7zMain.c
|
$(CXX) $(CFLAGS) 7zMain.c
|
||||||
|
|
||||||
7zAlloc.o: 7zAlloc.c
|
7zAlloc.o: 7zAlloc.c
|
||||||
$(CXX) $(CFLAGS) 7zAlloc.c
|
$(CXX) $(CFLAGS) ../../7zAlloc.c
|
||||||
|
|
||||||
7zBuf.o: ../../7zBuf.c
|
7zBuf.o: ../../7zBuf.c
|
||||||
$(CXX) $(CFLAGS) ../../7zBuf.c
|
$(CXX) $(CFLAGS) ../../7zBuf.c
|
||||||
@@ -44,6 +44,9 @@ LzmaDec.o: ../../LzmaDec.c
|
|||||||
Lzma2Dec.o: ../../Lzma2Dec.c
|
Lzma2Dec.o: ../../Lzma2Dec.c
|
||||||
$(CXX) $(CFLAGS) ../../Lzma2Dec.c
|
$(CXX) $(CFLAGS) ../../Lzma2Dec.c
|
||||||
|
|
||||||
|
Bra.o: ../../Bra.c
|
||||||
|
$(CXX) $(CFLAGS) ../../Bra.c
|
||||||
|
|
||||||
Bra86.o: ../../Bra86.c
|
Bra86.o: ../../Bra86.c
|
||||||
$(CXX) $(CFLAGS) ../../Bra86.c
|
$(CXX) $(CFLAGS) ../../Bra86.c
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaUtil.c -- Test application for LZMA compression
|
/* LzmaUtil.c -- Test application for LZMA compression
|
||||||
2009-08-14 : Igor Pavlov : Public domain */
|
2010-09-20 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
@@ -249,6 +249,6 @@ int MY_CDECL main(int numArgs, const char *args[])
|
|||||||
{
|
{
|
||||||
char rs[800] = { 0 };
|
char rs[800] = { 0 };
|
||||||
int res = main2(numArgs, args, rs);
|
int res = main2(numArgs, args, rs);
|
||||||
printf(rs);
|
fputs(rs, stdout);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
587
C/Util/SfxSetup/SfxSetup.c
Executable file
@@ -0,0 +1,587 @@
|
|||||||
|
/* SfxSetup.c - 7z SFX Setup
|
||||||
|
2010-12-13 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#ifndef UNICODE
|
||||||
|
#define UNICODE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _UNICODE
|
||||||
|
#define _UNICODE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _CONSOLE
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../../7z.h"
|
||||||
|
#include "../../7zAlloc.h"
|
||||||
|
#include "../../7zCrc.h"
|
||||||
|
#include "../../7zFile.h"
|
||||||
|
#include "../../CpuArch.h"
|
||||||
|
|
||||||
|
#define k_EXE_ExtIndex 1
|
||||||
|
|
||||||
|
static const char *kExts[] =
|
||||||
|
{
|
||||||
|
"bat",
|
||||||
|
"exe",
|
||||||
|
"inf",
|
||||||
|
"msi",
|
||||||
|
#ifdef UNDER_CE
|
||||||
|
"cab",
|
||||||
|
#endif
|
||||||
|
"html",
|
||||||
|
"htm"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *kNames[] =
|
||||||
|
{
|
||||||
|
"setup",
|
||||||
|
"install",
|
||||||
|
"run",
|
||||||
|
"start"
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned FindExt(const wchar_t *s, unsigned *extLen)
|
||||||
|
{
|
||||||
|
unsigned len = (unsigned)wcslen(s);
|
||||||
|
unsigned i;
|
||||||
|
for (i = len; i > 0; i--)
|
||||||
|
{
|
||||||
|
if (s[i - 1] == '.')
|
||||||
|
{
|
||||||
|
*extLen = len - i;
|
||||||
|
return i - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*extLen = 0;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) -= 0x20 : (c)))
|
||||||
|
|
||||||
|
static unsigned FindItem(const char **items, unsigned num, const wchar_t *s, unsigned len)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < num; i++)
|
||||||
|
{
|
||||||
|
const char *item = items[i];
|
||||||
|
unsigned itemLen = (unsigned)strlen(item);
|
||||||
|
unsigned j;
|
||||||
|
if (len != itemLen)
|
||||||
|
continue;
|
||||||
|
for (j = 0; j < len; j++)
|
||||||
|
{
|
||||||
|
unsigned c = item[j];
|
||||||
|
if (c != s[j] && MAKE_CHAR_UPPER(c) != s[j])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (j == len)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _CONSOLE
|
||||||
|
static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
|
||||||
|
{
|
||||||
|
ctrlType = ctrlType;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void PrintErrorMessage(const char *message)
|
||||||
|
{
|
||||||
|
#ifdef _CONSOLE
|
||||||
|
printf("\n7-Zip Error: %s\n", message);
|
||||||
|
#else
|
||||||
|
#ifdef UNDER_CE
|
||||||
|
WCHAR messageW[256 + 4];
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < 256 && message[i] != 0; i++)
|
||||||
|
messageW[i] = message[i];
|
||||||
|
messageW[i] = 0;
|
||||||
|
MessageBoxW(0, messageW, L"7-Zip Error", MB_ICONERROR);
|
||||||
|
#else
|
||||||
|
MessageBoxA(0, message, "7-Zip Error", MB_ICONERROR);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static WRes MyCreateDir(const WCHAR *name)
|
||||||
|
{
|
||||||
|
return CreateDirectoryW(name, NULL) ? 0 : GetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef UNDER_CE
|
||||||
|
#define kBufferSize (1 << 13)
|
||||||
|
#else
|
||||||
|
#define kBufferSize (1 << 15)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define kSignatureSearchLimit (1 << 22)
|
||||||
|
|
||||||
|
static Bool FindSignature(CSzFile *stream, UInt64 *resPos)
|
||||||
|
{
|
||||||
|
Byte buf[kBufferSize];
|
||||||
|
size_t numPrevBytes = 0;
|
||||||
|
*resPos = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
size_t processed, pos;
|
||||||
|
if (*resPos > kSignatureSearchLimit)
|
||||||
|
return False;
|
||||||
|
processed = kBufferSize - numPrevBytes;
|
||||||
|
if (File_Read(stream, buf + numPrevBytes, &processed) != 0)
|
||||||
|
return False;
|
||||||
|
processed += numPrevBytes;
|
||||||
|
if (processed < k7zStartHeaderSize ||
|
||||||
|
(processed == k7zStartHeaderSize && numPrevBytes != 0))
|
||||||
|
return False;
|
||||||
|
processed -= k7zStartHeaderSize;
|
||||||
|
for (pos = 0; pos <= processed; pos++)
|
||||||
|
{
|
||||||
|
for (; buf[pos] != '7' && pos <= processed; pos++);
|
||||||
|
if (pos > processed)
|
||||||
|
break;
|
||||||
|
if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0)
|
||||||
|
if (CrcCalc(buf + pos + 12, 20) == GetUi32(buf + pos + 8))
|
||||||
|
{
|
||||||
|
*resPos += pos;
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*resPos += processed;
|
||||||
|
numPrevBytes = k7zStartHeaderSize;
|
||||||
|
memmove(buf, buf + processed, k7zStartHeaderSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool DoesFileOrDirExist(const WCHAR *path)
|
||||||
|
{
|
||||||
|
WIN32_FIND_DATAW fd;
|
||||||
|
HANDLE handle;
|
||||||
|
handle = FindFirstFileW(path, &fd);
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
return False;
|
||||||
|
FindClose(handle);
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WRes RemoveDirWithSubItems(WCHAR *path)
|
||||||
|
{
|
||||||
|
WIN32_FIND_DATAW fd;
|
||||||
|
HANDLE handle;
|
||||||
|
WRes res = 0;
|
||||||
|
size_t len = wcslen(path);
|
||||||
|
wcscpy(path + len, L"*");
|
||||||
|
handle = FindFirstFileW(path, &fd);
|
||||||
|
path[len] = L'\0';
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
return GetLastError();
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (wcscmp(fd.cFileName, L".") != 0 &&
|
||||||
|
wcscmp(fd.cFileName, L"..") != 0)
|
||||||
|
{
|
||||||
|
wcscpy(path + len, fd.cFileName);
|
||||||
|
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
||||||
|
{
|
||||||
|
wcscat(path, L"\\");
|
||||||
|
res = RemoveDirWithSubItems(path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetFileAttributesW(path, 0);
|
||||||
|
if (DeleteFileW(path) == 0)
|
||||||
|
res = GetLastError();
|
||||||
|
}
|
||||||
|
if (res != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!FindNextFileW(handle, &fd))
|
||||||
|
{
|
||||||
|
res = GetLastError();
|
||||||
|
if (res == ERROR_NO_MORE_FILES)
|
||||||
|
res = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
path[len] = L'\0';
|
||||||
|
FindClose(handle);
|
||||||
|
if (res == 0)
|
||||||
|
{
|
||||||
|
if (!RemoveDirectoryW(path))
|
||||||
|
res = GetLastError();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _CONSOLE
|
||||||
|
int MY_CDECL main()
|
||||||
|
#else
|
||||||
|
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||||
|
#ifdef UNDER_CE
|
||||||
|
LPWSTR
|
||||||
|
#else
|
||||||
|
LPSTR
|
||||||
|
#endif
|
||||||
|
lpCmdLine, int nCmdShow)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
CFileInStream archiveStream;
|
||||||
|
CLookToRead lookStream;
|
||||||
|
CSzArEx db;
|
||||||
|
SRes res = SZ_OK;
|
||||||
|
ISzAlloc allocImp;
|
||||||
|
ISzAlloc allocTempImp;
|
||||||
|
WCHAR sfxPath[MAX_PATH + 2];
|
||||||
|
WCHAR path[MAX_PATH * 3 + 2];
|
||||||
|
size_t pathLen;
|
||||||
|
DWORD winRes;
|
||||||
|
const wchar_t *cmdLineParams;
|
||||||
|
const char *errorMessage = NULL;
|
||||||
|
Bool useShellExecute = True;
|
||||||
|
|
||||||
|
#ifdef _CONSOLE
|
||||||
|
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
|
||||||
|
#else
|
||||||
|
hInstance = hInstance;
|
||||||
|
hPrevInstance = hPrevInstance;
|
||||||
|
lpCmdLine = lpCmdLine;
|
||||||
|
nCmdShow = nCmdShow;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CrcGenerateTable();
|
||||||
|
|
||||||
|
allocImp.Alloc = SzAlloc;
|
||||||
|
allocImp.Free = SzFree;
|
||||||
|
|
||||||
|
allocTempImp.Alloc = SzAllocTemp;
|
||||||
|
allocTempImp.Free = SzFreeTemp;
|
||||||
|
|
||||||
|
FileInStream_CreateVTable(&archiveStream);
|
||||||
|
LookToRead_CreateVTable(&lookStream, False);
|
||||||
|
|
||||||
|
winRes = GetModuleFileNameW(NULL, sfxPath, MAX_PATH);
|
||||||
|
if (winRes == 0 || winRes > MAX_PATH)
|
||||||
|
return 1;
|
||||||
|
{
|
||||||
|
cmdLineParams = GetCommandLineW();
|
||||||
|
#ifndef UNDER_CE
|
||||||
|
{
|
||||||
|
Bool quoteMode = False;
|
||||||
|
for (;; cmdLineParams++)
|
||||||
|
{
|
||||||
|
wchar_t c = *cmdLineParams;
|
||||||
|
if (c == L'\"')
|
||||||
|
quoteMode = !quoteMode;
|
||||||
|
else if (c == 0 || (c == L' ' && !quoteMode))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
DWORD d;
|
||||||
|
winRes = GetTempPathW(MAX_PATH, path);
|
||||||
|
if (winRes == 0 || winRes > MAX_PATH)
|
||||||
|
return 1;
|
||||||
|
pathLen = wcslen(path);
|
||||||
|
d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId();
|
||||||
|
for (i = 0;; i++, d += GetTickCount())
|
||||||
|
{
|
||||||
|
if (i >= 100)
|
||||||
|
{
|
||||||
|
res = SZ_ERROR_FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
wcscpy(path + pathLen, L"7z");
|
||||||
|
|
||||||
|
{
|
||||||
|
wchar_t *s = path + wcslen(path);
|
||||||
|
UInt32 value = d;
|
||||||
|
unsigned k;
|
||||||
|
for (k = 0; k < 8; k++)
|
||||||
|
{
|
||||||
|
unsigned t = value & 0xF;
|
||||||
|
value >>= 4;
|
||||||
|
s[7 - k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
|
||||||
|
}
|
||||||
|
s[k] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DoesFileOrDirExist(path))
|
||||||
|
continue;
|
||||||
|
if (CreateDirectoryW(path, NULL))
|
||||||
|
{
|
||||||
|
wcscat(path, L"\\");
|
||||||
|
pathLen = wcslen(path);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (GetLastError() != ERROR_ALREADY_EXISTS)
|
||||||
|
{
|
||||||
|
res = SZ_ERROR_FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (res != SZ_OK)
|
||||||
|
errorMessage = "Can't create temp folder";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res != SZ_OK)
|
||||||
|
{
|
||||||
|
if (!errorMessage)
|
||||||
|
errorMessage = "Error";
|
||||||
|
PrintErrorMessage(errorMessage);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InFile_OpenW(&archiveStream.file, sfxPath) != 0)
|
||||||
|
{
|
||||||
|
errorMessage = "can not open input file";
|
||||||
|
res = SZ_ERROR_FAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UInt64 pos = 0;
|
||||||
|
if (!FindSignature(&archiveStream.file, &pos))
|
||||||
|
res = SZ_ERROR_FAIL;
|
||||||
|
else if (File_Seek(&archiveStream.file, (Int64 *)&pos, SZ_SEEK_SET) != 0)
|
||||||
|
res = SZ_ERROR_FAIL;
|
||||||
|
if (res != 0)
|
||||||
|
errorMessage = "Can't find 7z archive";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
lookStream.realStream = &archiveStream.s;
|
||||||
|
LookToRead_Init(&lookStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
SzArEx_Init(&db);
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
|
||||||
|
}
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
UInt32 executeFileIndex = (UInt32)(Int32)-1;
|
||||||
|
UInt32 minPrice = 1 << 30;
|
||||||
|
UInt32 i;
|
||||||
|
UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
|
||||||
|
Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
|
||||||
|
size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
|
||||||
|
|
||||||
|
for (i = 0; i < db.db.NumFiles; i++)
|
||||||
|
{
|
||||||
|
size_t offset = 0;
|
||||||
|
size_t outSizeProcessed = 0;
|
||||||
|
const CSzFileItem *f = db.db.Files + i;
|
||||||
|
size_t len;
|
||||||
|
WCHAR *temp;
|
||||||
|
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
|
||||||
|
|
||||||
|
if (len >= MAX_PATH)
|
||||||
|
{
|
||||||
|
res = SZ_ERROR_FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = path + pathLen;
|
||||||
|
|
||||||
|
SzArEx_GetFileNameUtf16(&db, i, temp);
|
||||||
|
{
|
||||||
|
res = SzArEx_Extract(&db, &lookStream.s, i,
|
||||||
|
&blockIndex, &outBuffer, &outBufferSize,
|
||||||
|
&offset, &outSizeProcessed,
|
||||||
|
&allocImp, &allocTempImp);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
CSzFile outFile;
|
||||||
|
size_t processedSize;
|
||||||
|
size_t j;
|
||||||
|
size_t nameStartPos = 0;
|
||||||
|
for (j = 0; temp[j] != 0; j++)
|
||||||
|
{
|
||||||
|
if (temp[j] == '/')
|
||||||
|
{
|
||||||
|
temp[j] = 0;
|
||||||
|
MyCreateDir(path);
|
||||||
|
temp[j] = CHAR_PATH_SEPARATOR;
|
||||||
|
nameStartPos = j + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f->IsDir)
|
||||||
|
{
|
||||||
|
MyCreateDir(path);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned extLen;
|
||||||
|
const WCHAR *name = temp + nameStartPos;
|
||||||
|
unsigned len = (unsigned)wcslen(name);
|
||||||
|
unsigned nameLen = FindExt(temp + nameStartPos, &extLen);
|
||||||
|
unsigned extPrice = FindItem(kExts, sizeof(kExts) / sizeof(kExts[0]), name + len - extLen, extLen);
|
||||||
|
unsigned namePrice = FindItem(kNames, sizeof(kNames) / sizeof(kNames[0]), name, nameLen);
|
||||||
|
|
||||||
|
unsigned price = namePrice + extPrice * 64 + (nameStartPos == 0 ? 0 : (1 << 12));
|
||||||
|
if (minPrice > price)
|
||||||
|
{
|
||||||
|
minPrice = price;
|
||||||
|
executeFileIndex = i;
|
||||||
|
useShellExecute = (extPrice != k_EXE_ExtIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DoesFileOrDirExist(path))
|
||||||
|
{
|
||||||
|
errorMessage = "Duplicate file";
|
||||||
|
res = SZ_ERROR_FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (OutFile_OpenW(&outFile, path))
|
||||||
|
{
|
||||||
|
errorMessage = "Can't open output file";
|
||||||
|
res = SZ_ERROR_FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
processedSize = outSizeProcessed;
|
||||||
|
if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
|
||||||
|
{
|
||||||
|
errorMessage = "Can't write output file";
|
||||||
|
res = SZ_ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
if (f->MTimeDefined)
|
||||||
|
{
|
||||||
|
FILETIME mTime;
|
||||||
|
mTime.dwLowDateTime = f->MTime.Low;
|
||||||
|
mTime.dwHighDateTime = f->MTime.High;
|
||||||
|
SetFileTime(outFile.handle, NULL, NULL, &mTime);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
|
SRes res2 = File_Close(&outFile);
|
||||||
|
if (res != SZ_OK)
|
||||||
|
break;
|
||||||
|
if (res2 != SZ_OK)
|
||||||
|
{
|
||||||
|
res = res2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef USE_WINDOWS_FILE
|
||||||
|
if (f->AttribDefined)
|
||||||
|
SetFileAttributesW(path, f->Attrib);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
if (executeFileIndex == (UInt32)(Int32)-1)
|
||||||
|
{
|
||||||
|
errorMessage = "There is no file to execute";
|
||||||
|
res = SZ_ERROR_FAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WCHAR *temp = path + pathLen;
|
||||||
|
UInt32 j;
|
||||||
|
SzArEx_GetFileNameUtf16(&db, executeFileIndex, temp);
|
||||||
|
for (j = 0; temp[j] != 0; j++)
|
||||||
|
if (temp[j] == '/')
|
||||||
|
temp[j] = CHAR_PATH_SEPARATOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IAlloc_Free(&allocImp, outBuffer);
|
||||||
|
}
|
||||||
|
SzArEx_Free(&db, &allocImp);
|
||||||
|
|
||||||
|
File_Close(&archiveStream.file);
|
||||||
|
|
||||||
|
if (res == SZ_OK)
|
||||||
|
{
|
||||||
|
HANDLE hProcess = 0;
|
||||||
|
if (useShellExecute)
|
||||||
|
{
|
||||||
|
SHELLEXECUTEINFO ei;
|
||||||
|
UINT32 executeRes;
|
||||||
|
BOOL success;
|
||||||
|
|
||||||
|
memset(&ei, 0, sizeof(ei));
|
||||||
|
ei.cbSize = sizeof(ei);
|
||||||
|
ei.lpFile = path;
|
||||||
|
ei.fMask = SEE_MASK_NOCLOSEPROCESS
|
||||||
|
#ifndef UNDER_CE
|
||||||
|
| SEE_MASK_FLAG_DDEWAIT
|
||||||
|
#endif
|
||||||
|
/* | SEE_MASK_NO_CONSOLE */
|
||||||
|
;
|
||||||
|
if (wcslen(cmdLineParams) != 0)
|
||||||
|
ei.lpParameters = cmdLineParams;
|
||||||
|
ei.nShow = SW_SHOWNORMAL; /* SW_HIDE; */
|
||||||
|
success = ShellExecuteEx(&ei);
|
||||||
|
executeRes = (UINT32)(UINT_PTR)ei.hInstApp;
|
||||||
|
if (!success || (executeRes <= 32 && executeRes != 0)) /* executeRes = 0 in Windows CE */
|
||||||
|
res = SZ_ERROR_FAIL;
|
||||||
|
else
|
||||||
|
hProcess = ei.hProcess;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
STARTUPINFOW si;
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
WCHAR cmdLine[MAX_PATH * 3];
|
||||||
|
|
||||||
|
wcscpy(cmdLine, path);
|
||||||
|
wcscat(cmdLine, cmdLineParams);
|
||||||
|
memset(&si, 0, sizeof(si));
|
||||||
|
si.cb = sizeof(si);
|
||||||
|
if (CreateProcessW(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == 0)
|
||||||
|
res = SZ_ERROR_FAIL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
hProcess = pi.hProcess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hProcess != 0)
|
||||||
|
{
|
||||||
|
WaitForSingleObject(hProcess, INFINITE);
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
path[pathLen] = L'\0';
|
||||||
|
RemoveDirWithSubItems(path);
|
||||||
|
|
||||||
|
if (res == SZ_OK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
if (res == SZ_ERROR_UNSUPPORTED)
|
||||||
|
errorMessage = "Decoder doesn't support this archive";
|
||||||
|
else if (res == SZ_ERROR_MEM)
|
||||||
|
errorMessage = "Can't allocate required memory";
|
||||||
|
else if (res == SZ_ERROR_CRC)
|
||||||
|
errorMessage = "CRC error";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!errorMessage)
|
||||||
|
errorMessage = "ERROR";
|
||||||
|
}
|
||||||
|
if (errorMessage)
|
||||||
|
PrintErrorMessage(errorMessage);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
198
C/Util/SfxSetup/SfxSetup.dsp
Executable file
@@ -0,0 +1,198 @@
|
|||||||
|
# Microsoft Developer Studio Project File - Name="SfxSetup" - Package Owner=<4>
|
||||||
|
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||||
|
# ** DO NOT EDIT **
|
||||||
|
|
||||||
|
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||||
|
|
||||||
|
CFG=SfxSetup - Win32 Debug
|
||||||
|
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||||
|
!MESSAGE use the Export Makefile command and run
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "SfxSetup.mak".
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE You can specify a configuration when running NMAKE
|
||||||
|
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "SfxSetup.mak" CFG="SfxSetup - Win32 Debug"
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE Possible choices for configuration are:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE "SfxSetup - Win32 Release" (based on "Win32 (x86) Application")
|
||||||
|
!MESSAGE "SfxSetup - Win32 Debug" (based on "Win32 (x86) Application")
|
||||||
|
!MESSAGE
|
||||||
|
|
||||||
|
# Begin Project
|
||||||
|
# PROP AllowPerConfigDependencies 0
|
||||||
|
# PROP Scc_ProjName ""
|
||||||
|
# PROP Scc_LocalPath ""
|
||||||
|
CPP=cl.exe
|
||||||
|
MTL=midl.exe
|
||||||
|
RSC=rc.exe
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "SfxSetup - Win32 Release"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "Release"
|
||||||
|
# PROP BASE Intermediate_Dir "Release"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "Release"
|
||||||
|
# PROP Intermediate_Dir "Release"
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||||
|
# ADD CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /YX /FD /c
|
||||||
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
|
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||||
|
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
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 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
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "SfxSetup - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "Debug"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "Debug"
|
||||||
|
# PROP Intermediate_Dir "Debug"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||||
|
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /YX /FD /GZ /c
|
||||||
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||||
|
# ADD RSC /l 0x419 /d "_DEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
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 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
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Begin Target
|
||||||
|
|
||||||
|
# Name "SfxSetup - Win32 Release"
|
||||||
|
# Name "SfxSetup - Win32 Debug"
|
||||||
|
# Begin Group "Common"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7z.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7zAlloc.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7zAlloc.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7zBuf.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7zBuf.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7zCrc.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7zCrc.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7zCrcOpt.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7zDec.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7zFile.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7zFile.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7zIn.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\7zStream.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Bcj2.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Bcj2.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Bra.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Bra.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Bra86.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\CpuArch.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\CpuArch.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Lzma2Dec.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Lzma2Dec.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\LzmaDec.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\LzmaDec.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Types.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\SfxSetup.c
|
||||||
|
# End Source File
|
||||||
|
# End Target
|
||||||
|
# End Project
|
||||||
29
C/Util/SfxSetup/SfxSetup.dsw
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||||
|
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "SfxSetup"=.\SfxSetup.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Global:
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<3>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
35
C/Util/SfxSetup/makefile
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
PROG = 7zS2.sfx
|
||||||
|
LIBS = $(LIBS)
|
||||||
|
CFLAGS = $(CFLAGS) -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_WARNINGS
|
||||||
|
|
||||||
|
C_OBJS = \
|
||||||
|
$O\7zAlloc.obj \
|
||||||
|
$O\7zBuf.obj \
|
||||||
|
$O\7zBuf2.obj \
|
||||||
|
$O\7zCrc.obj \
|
||||||
|
$O\7zCrcOpt.obj \
|
||||||
|
$O\7zFile.obj \
|
||||||
|
$O\7zDec.obj \
|
||||||
|
$O\7zIn.obj \
|
||||||
|
$O\7zStream.obj \
|
||||||
|
$O\Bcj2.obj \
|
||||||
|
$O\Bra.obj \
|
||||||
|
$O\Bra86.obj \
|
||||||
|
$O\CpuArch.obj \
|
||||||
|
$O\Lzma2Dec.obj \
|
||||||
|
$O\LzmaDec.obj \
|
||||||
|
|
||||||
|
7Z_OBJS = \
|
||||||
|
$O\SfxSetup.obj \
|
||||||
|
|
||||||
|
OBJS = \
|
||||||
|
$(7Z_OBJS) \
|
||||||
|
$(C_OBJS) \
|
||||||
|
$O\resource.res
|
||||||
|
|
||||||
|
!include "../../../CPP/Build.mak"
|
||||||
|
|
||||||
|
$(7Z_OBJS): $(*B).c
|
||||||
|
$(COMPL_O1)
|
||||||
|
$(C_OBJS): ../../$(*B).c
|
||||||
|
$(COMPL_O1)
|
||||||
35
C/Util/SfxSetup/makefile_con
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
PROG = 7zS2con.sfx
|
||||||
|
LIBS = $(LIBS)
|
||||||
|
CFLAGS = $(CFLAGS) -DUNICODE -D_UNICODE -D_CONSOLE
|
||||||
|
|
||||||
|
C_OBJS = \
|
||||||
|
$O\7zAlloc.obj \
|
||||||
|
$O\7zBuf.obj \
|
||||||
|
$O\7zBuf2.obj \
|
||||||
|
$O\7zCrc.obj \
|
||||||
|
$O\7zCrcOpt.obj \
|
||||||
|
$O\7zFile.obj \
|
||||||
|
$O\7zDec.obj \
|
||||||
|
$O\7zIn.obj \
|
||||||
|
$O\7zStream.obj \
|
||||||
|
$O\Bcj2.obj \
|
||||||
|
$O\Bra.obj \
|
||||||
|
$O\Bra86.obj \
|
||||||
|
$O\CpuArch.obj \
|
||||||
|
$O\Lzma2Dec.obj \
|
||||||
|
$O\LzmaDec.obj \
|
||||||
|
|
||||||
|
7Z_OBJS = \
|
||||||
|
$O\SfxSetup.obj \
|
||||||
|
|
||||||
|
OBJS = \
|
||||||
|
$(7Z_OBJS) \
|
||||||
|
$(C_OBJS) \
|
||||||
|
$O\resource.res
|
||||||
|
|
||||||
|
!include "../../../CPP/Build.mak"
|
||||||
|
|
||||||
|
$(7Z_OBJS): $(*B).c
|
||||||
|
$(COMPL_O1)
|
||||||
|
$(C_OBJS): ../../$(*B).c
|
||||||
|
$(COMPL_O1)
|
||||||
6
C/Util/SfxSetup/resource.rc
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#include "../../../CPP/7zip/MyVersionInfo.rc"
|
||||||
|
|
||||||
|
MY_VERSION_INFO_APP("7z Setup SFX small", "7zS2.sfx")
|
||||||
|
|
||||||
|
1 ICON "setup.ico"
|
||||||
|
|
||||||
BIN
C/Util/SfxSetup/setup.ico
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
20
C/Xz.h
@@ -1,14 +1,12 @@
|
|||||||
/* Xz.h - Xz interface
|
/* Xz.h - Xz interface
|
||||||
2009-04-15 : Igor Pavlov : Public domain */
|
2011-01-09 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __XZ_H
|
#ifndef __XZ_H
|
||||||
#define __XZ_H
|
#define __XZ_H
|
||||||
|
|
||||||
#include "Sha256.h"
|
#include "Sha256.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_BEGIN
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define XZ_ID_Subblock 1
|
#define XZ_ID_Subblock 1
|
||||||
#define XZ_ID_Delta 3
|
#define XZ_ID_Delta 3
|
||||||
@@ -140,7 +138,7 @@ typedef enum
|
|||||||
CODER_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
CODER_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
||||||
CODER_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
CODER_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
||||||
CODER_STATUS_NOT_FINISHED, /* stream was not finished */
|
CODER_STATUS_NOT_FINISHED, /* stream was not finished */
|
||||||
CODER_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
|
CODER_STATUS_NEEDS_MORE_INPUT /* you must provide more input bytes */
|
||||||
} ECoderStatus;
|
} ECoderStatus;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@@ -222,7 +220,8 @@ typedef struct
|
|||||||
Byte buf[XZ_BLOCK_HEADER_SIZE_MAX];
|
Byte buf[XZ_BLOCK_HEADER_SIZE_MAX];
|
||||||
} CXzUnpacker;
|
} CXzUnpacker;
|
||||||
|
|
||||||
SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc);
|
void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc);
|
||||||
|
void XzUnpacker_Init(CXzUnpacker *p);
|
||||||
void XzUnpacker_Free(CXzUnpacker *p);
|
void XzUnpacker_Free(CXzUnpacker *p);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -234,8 +233,9 @@ finishMode:
|
|||||||
Returns:
|
Returns:
|
||||||
SZ_OK
|
SZ_OK
|
||||||
status:
|
status:
|
||||||
LZMA_STATUS_FINISHED_WITH_MARK
|
CODER_STATUS_NOT_FINISHED,
|
||||||
LZMA_STATUS_NOT_FINISHED
|
CODER_STATUS_NEEDS_MORE_INPUT - maybe there are more xz streams,
|
||||||
|
call XzUnpacker_IsStreamWasFinished to check that current stream was finished
|
||||||
SZ_ERROR_DATA - Data error
|
SZ_ERROR_DATA - Data error
|
||||||
SZ_ERROR_MEM - Memory allocation error
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
@@ -249,8 +249,6 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
|||||||
|
|
||||||
Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p);
|
Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_END
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/* XzCrc64.c -- CRC64 calculation
|
/* XzCrc64.c -- CRC64 calculation
|
||||||
2009-04-15 : Igor Pavlov : Public domain */
|
2010-04-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "XzCrc64.h"
|
#include "XzCrc64.h"
|
||||||
|
|
||||||
#define kCrc64Poly 0xC96C5795D7870F42
|
#define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42)
|
||||||
UInt64 g_Crc64Table[256];
|
UInt64 g_Crc64Table[256];
|
||||||
|
|
||||||
void MY_FAST_CALL Crc64GenerateTable(void)
|
void MY_FAST_CALL Crc64GenerateTable(void)
|
||||||
|
|||||||
16
C/XzCrc64.h
@@ -1,5 +1,5 @@
|
|||||||
/* XzCrc64.c -- CRC64 calculation
|
/* XzCrc64.h -- CRC64 calculation
|
||||||
2009-04-15 : Igor Pavlov : Public domain */
|
2010-04-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __XZ_CRC64_H
|
#ifndef __XZ_CRC64_H
|
||||||
#define __XZ_CRC64_H
|
#define __XZ_CRC64_H
|
||||||
@@ -8,23 +8,19 @@
|
|||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_BEGIN
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern UInt64 g_Crc64Table[];
|
extern UInt64 g_Crc64Table[];
|
||||||
|
|
||||||
void MY_FAST_CALL Crc64GenerateTable(void);
|
void MY_FAST_CALL Crc64GenerateTable(void);
|
||||||
|
|
||||||
#define CRC64_INIT_VAL 0xFFFFFFFFFFFFFFFF
|
#define CRC64_INIT_VAL UINT64_CONST(0xFFFFFFFFFFFFFFFF)
|
||||||
#define CRC64_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFFFFFFFFFF)
|
#define CRC64_GET_DIGEST(crc) ((crc) ^ CRC64_INIT_VAL)
|
||||||
#define CRC64_UPDATE_BYTE(crc, b) (g_Crc64Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
#define CRC64_UPDATE_BYTE(crc, b) (g_Crc64Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||||
|
|
||||||
UInt64 MY_FAST_CALL Crc64Update(UInt64 crc, const void *data, size_t size);
|
UInt64 MY_FAST_CALL Crc64Update(UInt64 crc, const void *data, size_t size);
|
||||||
UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size);
|
UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_END
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
50
C/XzDec.c
@@ -1,5 +1,5 @@
|
|||||||
/* XzDec.c -- Xz Decode
|
/* XzDec.c -- Xz Decode
|
||||||
2009-06-08 : Igor Pavlov : Public domain */
|
2011-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
/* #define XZ_DUMP */
|
/* #define XZ_DUMP */
|
||||||
|
|
||||||
@@ -18,7 +18,8 @@
|
|||||||
#include "Lzma2Dec.h"
|
#include "Lzma2Dec.h"
|
||||||
|
|
||||||
#ifdef USE_SUBBLOCK
|
#ifdef USE_SUBBLOCK
|
||||||
#include "SbDec.h"
|
#include "Bcj3Dec.c"
|
||||||
|
#include "SbDec.c"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Xz.h"
|
#include "Xz.h"
|
||||||
@@ -72,7 +73,6 @@ SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *a
|
|||||||
{
|
{
|
||||||
CBraState *p = ((CBraState *)pp);
|
CBraState *p = ((CBraState *)pp);
|
||||||
alloc = alloc;
|
alloc = alloc;
|
||||||
p->encodeMode = 0;
|
|
||||||
p->ip = 0;
|
p->ip = 0;
|
||||||
if (p->methodId == XZ_ID_Delta)
|
if (p->methodId == XZ_ID_Delta)
|
||||||
{
|
{
|
||||||
@@ -195,7 +195,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, ISzAlloc *alloc)
|
SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
CBraState *decoder;
|
CBraState *decoder;
|
||||||
if (id != XZ_ID_Delta &&
|
if (id != XZ_ID_Delta &&
|
||||||
@@ -211,6 +211,7 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc)
|
|||||||
if (decoder == 0)
|
if (decoder == 0)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
decoder->methodId = (UInt32)id;
|
decoder->methodId = (UInt32)id;
|
||||||
|
decoder->encodeMode = encodeMode;
|
||||||
p->p = decoder;
|
p->p = decoder;
|
||||||
p->Free = BraState_Free;
|
p->Free = BraState_Free;
|
||||||
p->SetProps = BraState_SetProps;
|
p->SetProps = BraState_SetProps;
|
||||||
@@ -225,8 +226,8 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc)
|
|||||||
|
|
||||||
static void SbState_Free(void *pp, ISzAlloc *alloc)
|
static void SbState_Free(void *pp, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
CSubblockDec *p = (CSubblockDec *)pp;
|
CSbDec *p = (CSbDec *)pp;
|
||||||
SubblockDec_Free(p, alloc);
|
SbDec_Free(p);
|
||||||
alloc->Free(alloc, pp);
|
alloc->Free(alloc, pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,24 +241,32 @@ static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAl
|
|||||||
|
|
||||||
static void SbState_Init(void *pp)
|
static void SbState_Init(void *pp)
|
||||||
{
|
{
|
||||||
SubblockDec_Init((CSubblockDec *)pp);
|
SbDec_Init((CSbDec *)pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
|
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
|
||||||
{
|
{
|
||||||
ECoderStatus status;
|
CSbDec *p = (CSbDec *)pp;
|
||||||
SRes res = SubblockDec_Decode((CSubblockDec *)pp, dest, destLen, src, srcLen, finishMode, &status);
|
SRes res;
|
||||||
srcWasFinished = srcWasFinished;
|
srcWasFinished = srcWasFinished;
|
||||||
*wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
|
p->dest = dest;
|
||||||
|
p->destLen = *destLen;
|
||||||
|
p->src = src;
|
||||||
|
p->srcLen = *srcLen;
|
||||||
|
p->finish = finishMode; /* change it */
|
||||||
|
res = SbDec_Decode((CSbDec *)pp);
|
||||||
|
*destLen -= p->destLen;
|
||||||
|
*srcLen -= p->srcLen;
|
||||||
|
*wasFinished = (*destLen == 0 && *srcLen == 0); /* change it */
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
|
SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
CSubblockDec *decoder;
|
CSbDec *decoder;
|
||||||
p->p = 0;
|
p->p = 0;
|
||||||
decoder = alloc->Alloc(alloc, sizeof(CSubblockDec));
|
decoder = alloc->Alloc(alloc, sizeof(CSbDec));
|
||||||
if (decoder == 0)
|
if (decoder == 0)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
p->p = decoder;
|
p->p = decoder;
|
||||||
@@ -265,7 +274,8 @@ SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
|
|||||||
p->SetProps = SbState_SetProps;
|
p->SetProps = SbState_SetProps;
|
||||||
p->Init = SbState_Init;
|
p->Init = SbState_Init;
|
||||||
p->Code = SbState_Code;
|
p->Code = SbState_Code;
|
||||||
SubblockDec_Construct(decoder);
|
SbDec_Construct(decoder);
|
||||||
|
SbDec_SetAlloc(decoder, alloc);
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -369,7 +379,7 @@ SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId)
|
|||||||
}
|
}
|
||||||
if (coderIndex == 0)
|
if (coderIndex == 0)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
return BraState_SetFromMethod(sc, methodId, p->alloc);
|
return BraState_SetFromMethod(sc, methodId, 0, p->alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
|
SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
|
||||||
@@ -587,13 +597,17 @@ SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc)
|
void XzUnpacker_Init(CXzUnpacker *p)
|
||||||
{
|
{
|
||||||
MixCoder_Construct(&p->decoder, alloc);
|
|
||||||
p->state = XZ_STATE_STREAM_HEADER;
|
p->state = XZ_STATE_STREAM_HEADER;
|
||||||
p->pos = 0;
|
p->pos = 0;
|
||||||
p->numStreams = 0;
|
p->numStreams = 0;
|
||||||
return SZ_OK;
|
}
|
||||||
|
|
||||||
|
void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
MixCoder_Construct(&p->decoder, alloc);
|
||||||
|
XzUnpacker_Init(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XzUnpacker_Free(CXzUnpacker *p)
|
void XzUnpacker_Free(CXzUnpacker *p)
|
||||||
@@ -858,6 +872,8 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case XZ_STATE_BLOCK: break; /* to disable GCC warning */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|||||||
299
C/XzEnc.c
@@ -1,5 +1,5 @@
|
|||||||
/* XzEnc.c -- Xz Encode
|
/* XzEnc.c -- Xz Encode
|
||||||
2009-06-04 : Igor Pavlov : Public domain */
|
2011-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -9,7 +9,9 @@
|
|||||||
#include "Bra.h"
|
#include "Bra.h"
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
#ifdef USE_SUBBLOCK
|
#ifdef USE_SUBBLOCK
|
||||||
#include "SbEnc.h"
|
#include "Bcj3Enc.c"
|
||||||
|
#include "SbFind.c"
|
||||||
|
#include "SbEnc.c"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "XzEnc.h"
|
#include "XzEnc.h"
|
||||||
@@ -198,158 +200,147 @@ static size_t MyWrite(void *pp, const void *data, size_t size)
|
|||||||
|
|
||||||
/* ---------- CSeqInFilter ---------- */
|
/* ---------- CSeqInFilter ---------- */
|
||||||
|
|
||||||
/*
|
#define FILTER_BUF_SIZE (1 << 20)
|
||||||
typedef struct _IFilter
|
|
||||||
{
|
|
||||||
void *p;
|
|
||||||
void (*Free)(void *p, ISzAlloc *alloc);
|
|
||||||
SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAlloc *alloc);
|
|
||||||
void (*Init)(void *p);
|
|
||||||
size_t (*Filter)(void *p, Byte *data, SizeT destLen);
|
|
||||||
} IFilter;
|
|
||||||
|
|
||||||
#define FILT_BUF_SIZE (1 << 19)
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ISeqInStream p;
|
ISeqInStream p;
|
||||||
ISeqInStream *realStream;
|
ISeqInStream *realStream;
|
||||||
UInt32 x86State;
|
IStateCoder StateCoder;
|
||||||
UInt32 ip;
|
Byte *buf;
|
||||||
UInt64 processed;
|
size_t curPos;
|
||||||
CXzCheck check;
|
size_t endPos;
|
||||||
Byte buf[FILT_BUF_SIZE];
|
int srcWasFinished;
|
||||||
UInt32 bufferPos;
|
|
||||||
UInt32 convertedPosBegin;
|
|
||||||
UInt32 convertedPosEnd;
|
|
||||||
IFilter *filter;
|
|
||||||
} CSeqInFilter;
|
} CSeqInFilter;
|
||||||
|
|
||||||
static SRes SeqInFilter_Read(void *pp, void *data, size_t *size)
|
static SRes SeqInFilter_Read(void *pp, void *data, size_t *size)
|
||||||
{
|
{
|
||||||
CSeqInFilter *p = (CSeqInFilter *)pp;
|
CSeqInFilter *p = (CSeqInFilter *)pp;
|
||||||
size_t remSize = *size;
|
size_t sizeOriginal = *size;
|
||||||
|
if (sizeOriginal == 0)
|
||||||
|
return S_OK;
|
||||||
*size = 0;
|
*size = 0;
|
||||||
|
for (;;)
|
||||||
while (remSize > 0)
|
|
||||||
{
|
{
|
||||||
int i;
|
if (!p->srcWasFinished && p->curPos == p->endPos)
|
||||||
if (p->convertedPosBegin != p->convertedPosEnd)
|
|
||||||
{
|
{
|
||||||
UInt32 sizeTemp = p->convertedPosEnd - p->convertedPosBegin;
|
p->curPos = 0;
|
||||||
if (remSize < sizeTemp)
|
p->endPos = FILTER_BUF_SIZE;
|
||||||
sizeTemp = (UInt32)remSize;
|
RINOK(p->realStream->Read(p->realStream, p->buf, &p->endPos));
|
||||||
memmove(data, p->buf + p->convertedPosBegin, sizeTemp);
|
if (p->endPos == 0)
|
||||||
p->convertedPosBegin += sizeTemp;
|
p->srcWasFinished = 1;
|
||||||
data = (void *)((Byte *)data + sizeTemp);
|
|
||||||
remSize -= sizeTemp;
|
|
||||||
*size += sizeTemp;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
for (i = 0; p->convertedPosEnd + i < p->bufferPos; i++)
|
|
||||||
p->buf[i] = p->buf[i + p->convertedPosEnd];
|
|
||||||
p->bufferPos = i;
|
|
||||||
p->convertedPosBegin = p->convertedPosEnd = 0;
|
|
||||||
{
|
{
|
||||||
size_t processedSizeTemp = FILT_BUF_SIZE - p->bufferPos;
|
SizeT srcLen = p->endPos - p->curPos;
|
||||||
RINOK(p->realStream->Read(p->realStream, p->buf + p->bufferPos, &processedSizeTemp));
|
int wasFinished;
|
||||||
p->bufferPos = p->bufferPos + (UInt32)processedSizeTemp;
|
SRes res;
|
||||||
}
|
*size = sizeOriginal;
|
||||||
p->convertedPosEnd = (UInt32)p->filter->Filter(p->filter->p, p->buf, p->bufferPos);
|
res = p->StateCoder.Code(p->StateCoder.p, data, size, p->buf + p->curPos, &srcLen,
|
||||||
if (p->convertedPosEnd == 0)
|
p->srcWasFinished, CODER_FINISH_ANY, &wasFinished);
|
||||||
{
|
p->curPos += srcLen;
|
||||||
if (p->bufferPos == 0)
|
if (*size != 0 || srcLen == 0 || res != 0)
|
||||||
break;
|
return res;
|
||||||
else
|
|
||||||
{
|
|
||||||
p->convertedPosEnd = p->bufferPos;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (p->convertedPosEnd > p->bufferPos)
|
|
||||||
{
|
|
||||||
for (; p->bufferPos < p->convertedPosEnd; p->bufferPos++)
|
|
||||||
p->buf[p->bufferPos] = 0;
|
|
||||||
p->convertedPosEnd = (UInt32)p->filter->Filter(p->filter->p, p->buf, p->bufferPos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
static void SeqInFilter_Construct(CSeqInFilter *p)
|
||||||
typedef struct
|
|
||||||
{
|
{
|
||||||
ISeqInStream p;
|
p->buf = NULL;
|
||||||
ISeqInStream *realStream;
|
p->p.Read = SeqInFilter_Read;
|
||||||
CMixCoder mixCoder;
|
}
|
||||||
Byte buf[FILT_BUF_SIZE];
|
|
||||||
UInt32 bufPos;
|
|
||||||
UInt32 bufSize;
|
|
||||||
} CMixCoderSeqInStream;
|
|
||||||
|
|
||||||
static SRes CMixCoderSeqInStream_Read(void *pp, void *data, size_t *size)
|
static void SeqInFilter_Free(CSeqInFilter *p)
|
||||||
{
|
{
|
||||||
CMixCoderSeqInStream *p = (CMixCoderSeqInStream *)pp;
|
if (p->buf)
|
||||||
SRes res = SZ_OK;
|
|
||||||
size_t remSize = *size;
|
|
||||||
*size = 0;
|
|
||||||
while (remSize > 0)
|
|
||||||
{
|
{
|
||||||
if (p->bufPos == p->bufSize)
|
g_Alloc.Free(&g_Alloc, p->buf);
|
||||||
{
|
p->buf = NULL;
|
||||||
size_t curSize;
|
|
||||||
p->bufPos = p->bufSize = 0;
|
|
||||||
if (*size != 0)
|
|
||||||
break;
|
|
||||||
curSize = FILT_BUF_SIZE;
|
|
||||||
RINOK(p->realStream->Read(p->realStream, p->buf, &curSize));
|
|
||||||
p->bufSize = (UInt32)curSize;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
SizeT destLen = remSize;
|
|
||||||
SizeT srcLen = p->bufSize - p->bufPos;
|
|
||||||
res = MixCoder_Code(&p->mixCoder, data, &destLen, p->buf + p->bufPos, &srcLen, 0);
|
|
||||||
data = (void *)((Byte *)data + destLen);
|
|
||||||
remSize -= destLen;
|
|
||||||
*size += destLen;
|
|
||||||
p->bufPos += srcLen;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props)
|
||||||
|
{
|
||||||
|
if (!p->buf)
|
||||||
|
{
|
||||||
|
p->buf = g_Alloc.Alloc(&g_Alloc, FILTER_BUF_SIZE);
|
||||||
|
if (!p->buf)
|
||||||
|
return SZ_ERROR_MEM;
|
||||||
|
}
|
||||||
|
p->curPos = p->endPos = 0;
|
||||||
|
p->srcWasFinished = 0;
|
||||||
|
RINOK(BraState_SetFromMethod(&p->StateCoder, props->id, 1, &g_Alloc));
|
||||||
|
RINOK(p->StateCoder.SetProps(p->StateCoder.p, props->props, props->propsSize, &g_Alloc));
|
||||||
|
p->StateCoder.Init(p->StateCoder.p);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- CSbEncInStream ---------- */
|
||||||
|
|
||||||
#ifdef USE_SUBBLOCK
|
#ifdef USE_SUBBLOCK
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ISeqInStream p;
|
ISeqInStream p;
|
||||||
CSubblockEnc sb;
|
ISeqInStream *inStream;
|
||||||
UInt64 processed;
|
CSbEnc enc;
|
||||||
} CSbEncInStream;
|
} CSbEncInStream;
|
||||||
|
|
||||||
void SbEncInStream_Init(CSbEncInStream *p)
|
|
||||||
{
|
|
||||||
p->processed = 0;
|
|
||||||
SubblockEnc_Init(&p->sb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
|
static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
|
||||||
{
|
{
|
||||||
CSbEncInStream *p = (CSbEncInStream *)pp;
|
CSbEncInStream *p = (CSbEncInStream *)pp;
|
||||||
SRes res = SubblockEnc_Read(&p->sb, data, size);
|
size_t sizeOriginal = *size;
|
||||||
p->processed += *size;
|
if (sizeOriginal == 0)
|
||||||
return res;
|
return S_OK;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (p->enc.needRead && !p->enc.readWasFinished)
|
||||||
|
{
|
||||||
|
size_t processed = p->enc.needReadSizeMax;
|
||||||
|
RINOK(p->inStream->Read(p->inStream, p->enc.buf + p->enc.readPos, &processed));
|
||||||
|
p->enc.readPos += processed;
|
||||||
|
if (processed == 0)
|
||||||
|
{
|
||||||
|
p->enc.readWasFinished = True;
|
||||||
|
p->enc.isFinalFinished = True;
|
||||||
|
}
|
||||||
|
p->enc.needRead = False;
|
||||||
|
}
|
||||||
|
*size = sizeOriginal;
|
||||||
|
RINOK(SbEnc_Read(&p->enc, data, size));
|
||||||
|
if (*size != 0 || !p->enc.needRead)
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SbEncInStream_Construct(CSbEncInStream *p, ISzAlloc *alloc)
|
||||||
|
{
|
||||||
|
SbEnc_Construct(&p->enc, alloc);
|
||||||
|
p->p.Read = SbEncInStream_Read;
|
||||||
|
}
|
||||||
|
|
||||||
|
SRes SbEncInStream_Init(CSbEncInStream *p)
|
||||||
|
{
|
||||||
|
return SbEnc_Init(&p->enc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SbEncInStream_Free(CSbEncInStream *p)
|
||||||
|
{
|
||||||
|
SbEnc_Free(&p->enc);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/* CMixCoderSeqInStream inStream; */
|
|
||||||
CLzma2EncHandle lzma2;
|
CLzma2EncHandle lzma2;
|
||||||
#ifdef USE_SUBBLOCK
|
#ifdef USE_SUBBLOCK
|
||||||
CSbEncInStream sb;
|
CSbEncInStream sb;
|
||||||
#endif
|
#endif
|
||||||
|
CSeqInFilter filter;
|
||||||
ISzAlloc *alloc;
|
ISzAlloc *alloc;
|
||||||
ISzAlloc *bigAlloc;
|
ISzAlloc *bigAlloc;
|
||||||
} CLzma2WithFilters;
|
} CLzma2WithFilters;
|
||||||
@@ -361,9 +352,9 @@ static void Lzma2WithFilters_Construct(CLzma2WithFilters *p, ISzAlloc *alloc, IS
|
|||||||
p->bigAlloc = bigAlloc;
|
p->bigAlloc = bigAlloc;
|
||||||
p->lzma2 = NULL;
|
p->lzma2 = NULL;
|
||||||
#ifdef USE_SUBBLOCK
|
#ifdef USE_SUBBLOCK
|
||||||
p->sb.p.Read = SbEncInStream_Read;
|
SbEncInStream_Construct(&p->sb, alloc);
|
||||||
SubblockEnc_Construct(&p->sb.sb, p->alloc);
|
|
||||||
#endif
|
#endif
|
||||||
|
SeqInFilter_Construct(&p->filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p)
|
static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p)
|
||||||
@@ -376,8 +367,9 @@ static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p)
|
|||||||
|
|
||||||
static void Lzma2WithFilters_Free(CLzma2WithFilters *p)
|
static void Lzma2WithFilters_Free(CLzma2WithFilters *p)
|
||||||
{
|
{
|
||||||
|
SeqInFilter_Free(&p->filter);
|
||||||
#ifdef USE_SUBBLOCK
|
#ifdef USE_SUBBLOCK
|
||||||
SubblockEnc_Free(&p->sb.sb);
|
SbEncInStream_Free(&p->sb);
|
||||||
#endif
|
#endif
|
||||||
if (p->lzma2)
|
if (p->lzma2)
|
||||||
{
|
{
|
||||||
@@ -386,17 +378,28 @@ static void Lzma2WithFilters_Free(CLzma2WithFilters *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes Xz_Compress(CXzStream *xz,
|
void XzProps_Init(CXzProps *p)
|
||||||
CLzma2WithFilters *lzmaf,
|
|
||||||
ISeqOutStream *outStream,
|
|
||||||
ISeqInStream *inStream,
|
|
||||||
const CLzma2EncProps *lzma2Props,
|
|
||||||
Bool useSubblock,
|
|
||||||
ICompressProgress *progress)
|
|
||||||
{
|
{
|
||||||
xz->flags = XZ_CHECK_CRC32;
|
p->lzma2Props = 0;
|
||||||
|
p->filterProps = 0;
|
||||||
|
p->checkId = XZ_CHECK_CRC32;
|
||||||
|
}
|
||||||
|
|
||||||
RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, lzma2Props));
|
void XzFilterProps_Init(CXzFilterProps *p)
|
||||||
|
{
|
||||||
|
p->id = 0;
|
||||||
|
p->delta = 0;
|
||||||
|
p->ip= 0;
|
||||||
|
p->ipDefined = False;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
|
||||||
|
ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||||
|
const CXzProps *props, ICompressProgress *progress)
|
||||||
|
{
|
||||||
|
xz->flags = (Byte)props->checkId;
|
||||||
|
|
||||||
|
RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, props->lzma2Props));
|
||||||
RINOK(Xz_WriteHeader(xz->flags, outStream));
|
RINOK(Xz_WriteHeader(xz->flags, outStream));
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -404,15 +407,27 @@ static SRes Xz_Compress(CXzStream *xz,
|
|||||||
CSeqSizeOutStream seqSizeOutStream;
|
CSeqSizeOutStream seqSizeOutStream;
|
||||||
CXzBlock block;
|
CXzBlock block;
|
||||||
int filterIndex = 0;
|
int filterIndex = 0;
|
||||||
|
CXzFilter *filter = NULL;
|
||||||
|
const CXzFilterProps *fp = props->filterProps;
|
||||||
|
|
||||||
XzBlock_ClearFlags(&block);
|
XzBlock_ClearFlags(&block);
|
||||||
XzBlock_SetNumFilters(&block, 1 + (useSubblock ? 1 : 0));
|
XzBlock_SetNumFilters(&block, 1 + (fp ? 1 : 0));
|
||||||
|
|
||||||
if (useSubblock)
|
if (fp)
|
||||||
{
|
{
|
||||||
CXzFilter *f = &block.filters[filterIndex++];
|
filter = &block.filters[filterIndex++];
|
||||||
f->id = XZ_ID_Subblock;
|
filter->id = fp->id;
|
||||||
f->propsSize = 0;
|
filter->propsSize = 0;
|
||||||
|
if (fp->id == XZ_ID_Delta)
|
||||||
|
{
|
||||||
|
filter->props[0] = (Byte)(fp->delta - 1);
|
||||||
|
filter->propsSize = 1;
|
||||||
|
}
|
||||||
|
else if (fp->ipDefined)
|
||||||
|
{
|
||||||
|
SetUi32(filter->props, fp->ip);
|
||||||
|
filter->propsSize = 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -432,20 +447,30 @@ static SRes Xz_Compress(CXzStream *xz,
|
|||||||
checkInStream.realStream = inStream;
|
checkInStream.realStream = inStream;
|
||||||
SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags));
|
SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags));
|
||||||
|
|
||||||
#ifdef USE_SUBBLOCK
|
if (fp)
|
||||||
if (useSubblock)
|
|
||||||
{
|
{
|
||||||
lzmaf->sb.sb.inStream = &checkInStream.p;
|
#ifdef USE_SUBBLOCK
|
||||||
SubblockEnc_Init(&lzmaf->sb.sb);
|
if (fp->id == XZ_ID_Subblock)
|
||||||
|
{
|
||||||
|
lzmaf->sb.inStream = &checkInStream.p;
|
||||||
|
RINOK(SbEncInStream_Init(&lzmaf->sb));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
lzmaf->filter.realStream = &checkInStream.p;
|
||||||
|
RINOK(SeqInFilter_Init(&lzmaf->filter, filter));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
{
|
||||||
UInt64 packPos = seqSizeOutStream.processed;
|
UInt64 packPos = seqSizeOutStream.processed;
|
||||||
SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
|
SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
|
||||||
|
fp ?
|
||||||
#ifdef USE_SUBBLOCK
|
#ifdef USE_SUBBLOCK
|
||||||
useSubblock ? &lzmaf->sb.p:
|
(fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p:
|
||||||
#endif
|
#endif
|
||||||
|
&lzmaf->filter.p:
|
||||||
&checkInStream.p,
|
&checkInStream.p,
|
||||||
progress);
|
progress);
|
||||||
RINOK(res);
|
RINOK(res);
|
||||||
@@ -467,8 +492,7 @@ static SRes Xz_Compress(CXzStream *xz,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
|
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||||
const CLzma2EncProps *lzma2Props, Bool useSubblock,
|
const CXzProps *props, ICompressProgress *progress)
|
||||||
ICompressProgress *progress)
|
|
||||||
{
|
{
|
||||||
SRes res;
|
SRes res;
|
||||||
CXzStream xz;
|
CXzStream xz;
|
||||||
@@ -477,8 +501,7 @@ SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
|
|||||||
Lzma2WithFilters_Construct(&lzmaf, &g_Alloc, &g_BigAlloc);
|
Lzma2WithFilters_Construct(&lzmaf, &g_Alloc, &g_BigAlloc);
|
||||||
res = Lzma2WithFilters_Create(&lzmaf);
|
res = Lzma2WithFilters_Create(&lzmaf);
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
res = Xz_Compress(&xz, &lzmaf, outStream, inStream,
|
res = Xz_Compress(&xz, &lzmaf, outStream, inStream, props, progress);
|
||||||
lzma2Props, useSubblock, progress);
|
|
||||||
Lzma2WithFilters_Free(&lzmaf);
|
Lzma2WithFilters_Free(&lzmaf);
|
||||||
Xz_Free(&xz, &g_Alloc);
|
Xz_Free(&xz, &g_Alloc);
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
32
C/XzEnc.h
@@ -1,5 +1,5 @@
|
|||||||
/* XzEnc.h -- Xz Encode
|
/* XzEnc.h -- Xz Encode
|
||||||
2009-04-15 : Igor Pavlov : Public domain */
|
2011-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __XZ_ENC_H
|
#ifndef __XZ_ENC_H
|
||||||
#define __XZ_ENC_H
|
#define __XZ_ENC_H
|
||||||
@@ -8,18 +8,32 @@
|
|||||||
|
|
||||||
#include "Xz.h"
|
#include "Xz.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_BEGIN
|
||||||
extern "C" {
|
|
||||||
#endif
|
typedef struct
|
||||||
|
{
|
||||||
|
UInt32 id;
|
||||||
|
UInt32 delta;
|
||||||
|
UInt32 ip;
|
||||||
|
int ipDefined;
|
||||||
|
} CXzFilterProps;
|
||||||
|
|
||||||
|
void XzFilterProps_Init(CXzFilterProps *p);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const CLzma2EncProps *lzma2Props;
|
||||||
|
const CXzFilterProps *filterProps;
|
||||||
|
unsigned checkId;
|
||||||
|
} CXzProps;
|
||||||
|
|
||||||
|
void XzProps_Init(CXzProps *p);
|
||||||
|
|
||||||
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
|
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||||
const CLzma2EncProps *lzma2Props, Bool useSubblock,
|
const CXzProps *props, ICompressProgress *progress);
|
||||||
ICompressProgress *progress);
|
|
||||||
|
|
||||||
SRes Xz_EncodeEmpty(ISeqOutStream *outStream);
|
SRes Xz_EncodeEmpty(ISeqOutStream *outStream);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_END
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
41
C/XzIn.c
@@ -1,5 +1,5 @@
|
|||||||
/* XzIn.c - Xz input
|
/* XzIn.c - Xz input
|
||||||
2009-06-19 : Igor Pavlov : Public domain */
|
2011-02-01 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -152,39 +152,38 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff
|
|||||||
|
|
||||||
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
|
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
|
||||||
{
|
{
|
||||||
Int64 i = 0;
|
UInt32 total = 0;
|
||||||
*startOffset += XZ_STREAM_FOOTER_SIZE;
|
*startOffset += XZ_STREAM_FOOTER_SIZE;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
int j;
|
size_t i;
|
||||||
size_t processedSize;
|
|
||||||
#define TEMP_BUF_SIZE (1 << 10)
|
#define TEMP_BUF_SIZE (1 << 10)
|
||||||
Byte tempBuf[TEMP_BUF_SIZE];
|
Byte tempBuf[TEMP_BUF_SIZE];
|
||||||
if (*startOffset < XZ_STREAM_FOOTER_SIZE || i > (1 << 16))
|
if (*startOffset < XZ_STREAM_FOOTER_SIZE || total > (1 << 16))
|
||||||
return SZ_ERROR_NO_ARCHIVE;
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
processedSize = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset;
|
i = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset;
|
||||||
i += processedSize;
|
total += (UInt32)i;
|
||||||
*startOffset = -(Int64)processedSize;
|
*startOffset = -(Int64)i;
|
||||||
RINOK(SeekFromCur(stream, startOffset));
|
RINOK(SeekFromCur(stream, startOffset));
|
||||||
RINOK(LookInStream_Read2(stream, tempBuf, processedSize, SZ_ERROR_NO_ARCHIVE));
|
RINOK(LookInStream_Read2(stream, tempBuf, i, SZ_ERROR_NO_ARCHIVE));
|
||||||
for (j = (int)processedSize; j >= 0; j--)
|
for (; i != 0; i--)
|
||||||
if (tempBuf[j -1] != 0)
|
if (tempBuf[i - 1] != 0)
|
||||||
break;
|
break;
|
||||||
if (j != 0)
|
if (i != 0)
|
||||||
{
|
{
|
||||||
if ((j & 3) != 0)
|
if ((i & 3) != 0)
|
||||||
return SZ_ERROR_NO_ARCHIVE;
|
|
||||||
*startOffset += j;
|
|
||||||
if (*startOffset < XZ_STREAM_FOOTER_SIZE)
|
|
||||||
return SZ_ERROR_NO_ARCHIVE;
|
|
||||||
*startOffset -= XZ_STREAM_FOOTER_SIZE;
|
|
||||||
RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));
|
|
||||||
RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
|
|
||||||
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
|
|
||||||
return SZ_ERROR_NO_ARCHIVE;
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
|
*startOffset += i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (*startOffset < XZ_STREAM_FOOTER_SIZE)
|
||||||
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
|
*startOffset -= XZ_STREAM_FOOTER_SIZE;
|
||||||
|
RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));
|
||||||
|
RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
|
||||||
|
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
|
||||||
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->flags = (CXzStreamFlags)GetBe16(buf + 8);
|
p->flags = (CXzStreamFlags)GetBe16(buf + 8);
|
||||||
|
|||||||
@@ -3,19 +3,18 @@
|
|||||||
#ifndef __7Z_COMPRESSION_MODE_H
|
#ifndef __7Z_COMPRESSION_MODE_H
|
||||||
#define __7Z_COMPRESSION_MODE_H
|
#define __7Z_COMPRESSION_MODE_H
|
||||||
|
|
||||||
#include "../../../Common/MyString.h"
|
#include "../../Common/MethodId.h"
|
||||||
|
|
||||||
#include "../../../Windows/PropVariant.h"
|
|
||||||
|
|
||||||
#include "../../Common/MethodProps.h"
|
#include "../../Common/MethodProps.h"
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
struct CMethodFull: public CMethod
|
struct CMethodFull: public CProps
|
||||||
{
|
{
|
||||||
|
CMethodId Id;
|
||||||
UInt32 NumInStreams;
|
UInt32 NumInStreams;
|
||||||
UInt32 NumOutStreams;
|
UInt32 NumOutStreams;
|
||||||
|
|
||||||
bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
|
bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,15 @@ static void ConvertBindInfoToFolderItemInfo(const NCoderMixer::CBindInfo &bindIn
|
|||||||
folder.PackStreams.Add(bindInfo.InStreams[i]);
|
folder.PackStreams.Add(bindInfo.InStreams[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce, IUnknown *coder)
|
||||||
|
{
|
||||||
|
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
||||||
|
coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
|
||||||
|
if (setCoderProperties)
|
||||||
|
return props.SetCoderProps(setCoderProperties, dataSizeReduce);
|
||||||
|
return props.AreThereNonOptionalProps() ? E_INVALIDARG : S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT CEncoder::CreateMixerCoder(
|
HRESULT CEncoder::CreateMixerCoder(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
const UInt64 *inSizeForReduce)
|
const UInt64 *inSizeForReduce)
|
||||||
@@ -86,8 +95,7 @@ HRESULT CEncoder::CreateMixerCoder(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
RINOK(SetCoderProps2(methodFull, inSizeForReduce, encoderCommon));
|
||||||
RINOK(SetMethodProperties(methodFull, inSizeForReduce, encoderCommon));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
CMyComPtr<ICryptoResetSalt> resetSalt;
|
CMyComPtr<ICryptoResetSalt> resetSalt;
|
||||||
@@ -193,11 +201,9 @@ HRESULT CEncoder::Encode(
|
|||||||
// UInt64 outStreamStartPos;
|
// UInt64 outStreamStartPos;
|
||||||
// RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
|
// RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
|
||||||
|
|
||||||
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec =
|
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2;
|
||||||
new CSequentialInStreamSizeCount2;
|
|
||||||
CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
|
CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
|
||||||
CSequentialOutStreamSizeCount *outStreamSizeCountSpec =
|
CSequentialOutStreamSizeCount *outStreamSizeCountSpec = new CSequentialOutStreamSizeCount;
|
||||||
new CSequentialOutStreamSizeCount;
|
|
||||||
CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;
|
CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;
|
||||||
|
|
||||||
inStreamSizeCountSpec->Init(inStream);
|
inStreamSizeCountSpec->Init(inStream);
|
||||||
@@ -226,13 +232,11 @@ HRESULT CEncoder::Encode(
|
|||||||
_mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
|
_mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
|
||||||
if (writeCoderProperties != NULL)
|
if (writeCoderProperties != NULL)
|
||||||
{
|
{
|
||||||
CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
|
CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;
|
||||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||||
outStreamSpec->Init();
|
outStreamSpec->Init();
|
||||||
writeCoderProperties->WriteCoderProperties(outStream);
|
writeCoderProperties->WriteCoderProperties(outStream);
|
||||||
size_t size = outStreamSpec->GetSize();
|
outStreamSpec->CopyToBuffer(encodingInfo.Props);
|
||||||
encodingInfo.Props.SetCapacity(size);
|
|
||||||
memmove(encodingInfo.Props, outStreamSpec->GetBuffer(), size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,8 +254,7 @@ HRESULT CEncoder::Encode(
|
|||||||
RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
|
RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
|
||||||
&outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
|
&outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
|
||||||
|
|
||||||
ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods,
|
ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods, folderItem);
|
||||||
folderItem);
|
|
||||||
|
|
||||||
packSizes.Add(outStreamSizeCountSpec->GetSize());
|
packSizes.Add(outStreamSizeCountSpec->GetSize());
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,14 @@
|
|||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "7zHandler.h"
|
#include "../../../Common/ComTry.h"
|
||||||
#include "7zFolderOutStream.h"
|
|
||||||
|
#include "../../Common/ProgressUtils.h"
|
||||||
|
|
||||||
#include "7zDecode.h"
|
#include "7zDecode.h"
|
||||||
// #include "7z1Decode.h"
|
// #include "7z1Decode.h"
|
||||||
|
#include "7zFolderOutStream.h"
|
||||||
#include "../../../Common/ComTry.h"
|
#include "7zHandler.h"
|
||||||
#include "../../Common/StreamObjects.h"
|
|
||||||
#include "../../Common/ProgressUtils.h"
|
|
||||||
#include "../../Common/LimitedStreams.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
@@ -73,13 +72,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
|
CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
|
||||||
for(UInt32 ii = 0; ii < numItems; ii++)
|
for (UInt32 ii = 0; ii < numItems; ii++)
|
||||||
{
|
{
|
||||||
// UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
|
// UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
|
||||||
UInt32 ref2Index = allFilesMode ? ii : indices[ii];
|
UInt32 ref2Index = allFilesMode ? ii : indices[ii];
|
||||||
// const CRef2 &ref2 = _refs[ref2Index];
|
// const CRef2 &ref2 = _refs[ref2Index];
|
||||||
|
|
||||||
// for(UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)
|
// for (UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)
|
||||||
{
|
{
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
// const CRef &ref = ref2.Refs[ri];
|
// const CRef &ref = ref2.Refs[ri];
|
||||||
@@ -138,7 +137,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extractCallback->SetTotal(importantTotalUnpacked);
|
RINOK(extractCallback->SetTotal(importantTotalUnpacked));
|
||||||
|
|
||||||
CDecoder decoder(
|
CDecoder decoder(
|
||||||
#ifdef _ST_MODE
|
#ifdef _ST_MODE
|
||||||
@@ -149,27 +148,26 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
);
|
);
|
||||||
// CDecoder1 decoder;
|
// CDecoder1 decoder;
|
||||||
|
|
||||||
UInt64 currentTotalPacked = 0;
|
UInt64 totalPacked = 0;
|
||||||
UInt64 currentTotalUnpacked = 0;
|
UInt64 totalUnpacked = 0;
|
||||||
UInt64 totalFolderUnpacked;
|
UInt64 curPacked, curUnpacked;
|
||||||
UInt64 totalFolderPacked;
|
|
||||||
|
|
||||||
CLocalProgress *lps = new CLocalProgress;
|
CLocalProgress *lps = new CLocalProgress;
|
||||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||||
lps->Init(extractCallback, false);
|
lps->Init(extractCallback, false);
|
||||||
|
|
||||||
for(int i = 0; i < extractFolderInfoVector.Size(); i++,
|
for (int i = 0;; i++, totalUnpacked += curUnpacked, totalPacked += curPacked)
|
||||||
currentTotalUnpacked += totalFolderUnpacked,
|
|
||||||
currentTotalPacked += totalFolderPacked)
|
|
||||||
{
|
{
|
||||||
lps->OutSize = currentTotalUnpacked;
|
lps->OutSize = totalUnpacked;
|
||||||
lps->InSize = currentTotalPacked;
|
lps->InSize = totalPacked;
|
||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
|
|
||||||
|
if (i >= extractFolderInfoVector.Size())
|
||||||
|
break;
|
||||||
|
|
||||||
const CExtractFolderInfo &efi = extractFolderInfoVector[i];
|
const CExtractFolderInfo &efi = extractFolderInfoVector[i];
|
||||||
totalFolderUnpacked = efi.UnpackSize;
|
curUnpacked = efi.UnpackSize;
|
||||||
|
curPacked = 0;
|
||||||
totalFolderPacked = 0;
|
|
||||||
|
|
||||||
CFolderOutStream *folderOutStream = new CFolderOutStream;
|
CFolderOutStream *folderOutStream = new CFolderOutStream;
|
||||||
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
|
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
|
||||||
@@ -187,7 +185,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
else
|
else
|
||||||
startIndex = db.FolderStartFileIndex[efi.FolderIndex];
|
startIndex = db.FolderStartFileIndex[efi.FolderIndex];
|
||||||
|
|
||||||
|
|
||||||
HRESULT result = folderOutStream->Init(&db,
|
HRESULT result = folderOutStream->Init(&db,
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
volume.StartRef2Index,
|
volume.StartRef2Index,
|
||||||
@@ -205,7 +202,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
CNum folderIndex = efi.FolderIndex;
|
CNum folderIndex = efi.FolderIndex;
|
||||||
const CFolder &folderInfo = db.Folders[folderIndex];
|
const CFolder &folderInfo = db.Folders[folderIndex];
|
||||||
|
|
||||||
totalFolderPacked = _db.GetFolderFullPackSize(folderIndex);
|
curPacked = _db.GetFolderFullPackSize(folderIndex);
|
||||||
|
|
||||||
CNum packStreamIndex = db.FolderStartPackStreamIndex[folderIndex];
|
CNum packStreamIndex = db.FolderStartPackStreamIndex[folderIndex];
|
||||||
UInt64 folderStartPackPos = db.GetFolderStreamPos(folderIndex, 0);
|
UInt64 folderStartPackPos = db.GetFolderStreamPos(folderIndex, 0);
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ HRESULT CFolderInStream::OpenStream()
|
|||||||
_filePos = 0;
|
_filePos = 0;
|
||||||
while (_fileIndex < _numFiles)
|
while (_fileIndex < _numFiles)
|
||||||
{
|
{
|
||||||
_currentSizeIsDefined = false;
|
|
||||||
CMyComPtr<ISequentialInStream> stream;
|
CMyComPtr<ISequentialInStream> stream;
|
||||||
HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream);
|
HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream);
|
||||||
if (result != S_OK && result != S_FALSE)
|
if (result != S_OK && result != S_FALSE)
|
||||||
@@ -40,26 +39,22 @@ HRESULT CFolderInStream::OpenStream()
|
|||||||
_fileIndex++;
|
_fileIndex++;
|
||||||
_inStreamWithHashSpec->SetStream(stream);
|
_inStreamWithHashSpec->SetStream(stream);
|
||||||
_inStreamWithHashSpec->Init();
|
_inStreamWithHashSpec->Init();
|
||||||
if (!stream)
|
if (stream)
|
||||||
{
|
{
|
||||||
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
_fileIsOpen = true;
|
||||||
Sizes.Add(0);
|
CMyComPtr<IStreamGetSize> streamGetSize;
|
||||||
Processed.Add(result == S_OK);
|
stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
|
||||||
AddDigest();
|
if (streamGetSize)
|
||||||
continue;
|
|
||||||
}
|
|
||||||
CMyComPtr<IStreamGetSize> streamGetSize;
|
|
||||||
if (stream.QueryInterface(IID_IStreamGetSize, &streamGetSize) == S_OK)
|
|
||||||
{
|
|
||||||
if(streamGetSize)
|
|
||||||
{
|
{
|
||||||
_currentSizeIsDefined = true;
|
|
||||||
RINOK(streamGetSize->GetSize(&_currentSize));
|
RINOK(streamGetSize->GetSize(&_currentSize));
|
||||||
|
_currentSizeIsDefined = true;
|
||||||
}
|
}
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||||
_fileIsOpen = true;
|
Sizes.Add(0);
|
||||||
return S_OK;
|
Processed.Add(result == S_OK);
|
||||||
|
AddDigest();
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -74,6 +69,7 @@ HRESULT CFolderInStream::CloseStream()
|
|||||||
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||||
_inStreamWithHashSpec->ReleaseStream();
|
_inStreamWithHashSpec->ReleaseStream();
|
||||||
_fileIsOpen = false;
|
_fileIsOpen = false;
|
||||||
|
_currentSizeIsDefined = false;
|
||||||
Processed.Add(true);
|
Processed.Add(true);
|
||||||
Sizes.Add(_filePos);
|
Sizes.Add(_filePos);
|
||||||
AddDigest();
|
AddDigest();
|
||||||
@@ -82,43 +78,40 @@ HRESULT CFolderInStream::CloseStream()
|
|||||||
|
|
||||||
STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||||
{
|
{
|
||||||
UInt32 realProcessedSize = 0;
|
if (processedSize != 0)
|
||||||
while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0)
|
*processedSize = 0;
|
||||||
|
while (size > 0)
|
||||||
{
|
{
|
||||||
if (_fileIsOpen)
|
if (_fileIsOpen)
|
||||||
{
|
{
|
||||||
UInt32 localProcessedSize;
|
UInt32 processed2;
|
||||||
RINOK(_inStreamWithHash->Read(
|
RINOK(_inStreamWithHash->Read(data, size, &processed2));
|
||||||
((Byte *)data) + realProcessedSize, size, &localProcessedSize));
|
if (processed2 == 0)
|
||||||
if (localProcessedSize == 0)
|
|
||||||
{
|
{
|
||||||
RINOK(CloseStream());
|
RINOK(CloseStream());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
realProcessedSize += localProcessedSize;
|
if (processedSize != 0)
|
||||||
_filePos += localProcessedSize;
|
*processedSize = processed2;
|
||||||
size -= localProcessedSize;
|
_filePos += processed2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
if (_fileIndex >= _numFiles)
|
||||||
{
|
break;
|
||||||
RINOK(OpenStream());
|
RINOK(OpenStream());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (processedSize != 0)
|
|
||||||
*processedSize = realProcessedSize;
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
|
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
|
||||||
{
|
{
|
||||||
*value = 0;
|
*value = 0;
|
||||||
int subStreamIndex = (int)subStream;
|
int index2 = (int)subStream;
|
||||||
if (subStreamIndex < 0 || subStream > Sizes.Size())
|
if (index2 < 0 || subStream > Sizes.Size())
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
if (subStreamIndex < Sizes.Size())
|
if (index2 < Sizes.Size())
|
||||||
{
|
{
|
||||||
*value= Sizes[subStreamIndex];
|
*value = Sizes[index2];
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
if (!_currentSizeIsDefined)
|
if (!_currentSizeIsDefined)
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
// 7z/FolderInStream.h
|
// 7zFolderInStream.h
|
||||||
|
|
||||||
#ifndef __7Z_FOLDERINSTREAM_H
|
#ifndef __7Z_FOLDER_IN_STREAM_H
|
||||||
#define __7Z_FOLDERINSTREAM_H
|
#define __7Z_FOLDER_IN_STREAM_H
|
||||||
|
|
||||||
#include "7zItem.h"
|
|
||||||
#include "7zHeader.h"
|
|
||||||
|
|
||||||
|
#include "../../ICoder.h"
|
||||||
#include "../IArchive.h"
|
#include "../IArchive.h"
|
||||||
#include "../Common/InStreamWithCRC.h"
|
#include "../Common/InStreamWithCRC.h"
|
||||||
#include "../../IStream.h"
|
|
||||||
#include "../../ICoder.h"
|
#include "7zItem.h"
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
@@ -19,26 +17,14 @@ class CFolderInStream:
|
|||||||
public ICompressGetSubStreamSize,
|
public ICompressGetSubStreamSize,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
|
|
||||||
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
|
|
||||||
|
|
||||||
CFolderInStream();
|
|
||||||
|
|
||||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
|
|
||||||
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
|
|
||||||
private:
|
|
||||||
CSequentialInStreamWithCRC *_inStreamWithHashSpec;
|
CSequentialInStreamWithCRC *_inStreamWithHashSpec;
|
||||||
CMyComPtr<ISequentialInStream> _inStreamWithHash;
|
CMyComPtr<ISequentialInStream> _inStreamWithHash;
|
||||||
CMyComPtr<IArchiveUpdateCallback> _updateCallback;
|
CMyComPtr<IArchiveUpdateCallback> _updateCallback;
|
||||||
|
|
||||||
bool _currentSizeIsDefined;
|
bool _currentSizeIsDefined;
|
||||||
UInt64 _currentSize;
|
|
||||||
|
|
||||||
bool _fileIsOpen;
|
bool _fileIsOpen;
|
||||||
|
UInt64 _currentSize;
|
||||||
UInt64 _filePos;
|
UInt64 _filePos;
|
||||||
|
|
||||||
const UInt32 *_fileIndices;
|
const UInt32 *_fileIndices;
|
||||||
UInt32 _numFiles;
|
UInt32 _numFiles;
|
||||||
UInt32 _fileIndex;
|
UInt32 _fileIndex;
|
||||||
@@ -46,12 +32,18 @@ private:
|
|||||||
HRESULT OpenStream();
|
HRESULT OpenStream();
|
||||||
HRESULT CloseStream();
|
HRESULT CloseStream();
|
||||||
void AddDigest();
|
void AddDigest();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Init(IArchiveUpdateCallback *updateCallback,
|
|
||||||
const UInt32 *fileIndices, UInt32 numFiles);
|
|
||||||
CRecordVector<bool> Processed;
|
CRecordVector<bool> Processed;
|
||||||
CRecordVector<UInt32> CRCs;
|
CRecordVector<UInt32> CRCs;
|
||||||
CRecordVector<UInt64> Sizes;
|
CRecordVector<UInt64> Sizes;
|
||||||
|
|
||||||
|
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
|
||||||
|
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||||
|
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
|
||||||
|
|
||||||
|
CFolderInStream();
|
||||||
|
void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *fileIndices, UInt32 numFiles);
|
||||||
UInt64 GetFullSize() const
|
UInt64 GetFullSize() const
|
||||||
{
|
{
|
||||||
UInt64 size = 0;
|
UInt64 size = 0;
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ CFolderOutStream::CFolderOutStream()
|
|||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CFolderOutStream::Init(
|
HRESULT CFolderOutStream::Init(
|
||||||
const CArchiveDatabaseEx *archiveDatabase,
|
const CArchiveDatabaseEx *db,
|
||||||
UInt32 ref2Offset, UInt32 startIndex,
|
UInt32 ref2Offset, UInt32 startIndex,
|
||||||
const CBoolVector *extractStatuses,
|
const CBoolVector *extractStatuses,
|
||||||
IArchiveExtractCallback *extractCallback,
|
IArchiveExtractCallback *extractCallback,
|
||||||
bool testMode, bool checkCrc)
|
bool testMode, bool checkCrc)
|
||||||
{
|
{
|
||||||
_db = archiveDatabase;
|
_db = db;
|
||||||
_ref2Offset = ref2Offset;
|
_ref2Offset = ref2Offset;
|
||||||
_startIndex = startIndex;
|
_startIndex = startIndex;
|
||||||
|
|
||||||
@@ -121,6 +121,15 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CFolderOutStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
|
||||||
|
{
|
||||||
|
*value = 0;
|
||||||
|
if ((int)subStream >= _extractStatuses->Size())
|
||||||
|
return S_FALSE;
|
||||||
|
*value = _db->Files[_startIndex + (int)subStream].Size;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
|
HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
|
||||||
{
|
{
|
||||||
while (_currentIndex < _extractStatuses->Size())
|
while (_currentIndex < _extractStatuses->Size())
|
||||||
|
|||||||
@@ -3,17 +3,18 @@
|
|||||||
#ifndef __7Z_FOLDER_OUT_STREAM_H
|
#ifndef __7Z_FOLDER_OUT_STREAM_H
|
||||||
#define __7Z_FOLDER_OUT_STREAM_H
|
#define __7Z_FOLDER_OUT_STREAM_H
|
||||||
|
|
||||||
#include "7zIn.h"
|
|
||||||
|
|
||||||
#include "../../IStream.h"
|
#include "../../IStream.h"
|
||||||
#include "../IArchive.h"
|
#include "../IArchive.h"
|
||||||
#include "../Common/OutStreamWithCRC.h"
|
#include "../Common/OutStreamWithCRC.h"
|
||||||
|
|
||||||
|
#include "7zIn.h"
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
class CFolderOutStream:
|
class CFolderOutStream:
|
||||||
public ISequentialOutStream,
|
public ISequentialOutStream,
|
||||||
|
public ICompressGetSubStreamSize,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
COutStreamWithCRC *_crcStreamSpec;
|
COutStreamWithCRC *_crcStreamSpec;
|
||||||
@@ -34,14 +35,15 @@ class CFolderOutStream:
|
|||||||
HRESULT CloseFileAndSetResult();
|
HRESULT CloseFileAndSetResult();
|
||||||
HRESULT ProcessEmptyFiles();
|
HRESULT ProcessEmptyFiles();
|
||||||
public:
|
public:
|
||||||
MY_UNKNOWN_IMP
|
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
|
||||||
|
|
||||||
CFolderOutStream();
|
CFolderOutStream();
|
||||||
|
|
||||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||||
|
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
|
||||||
|
|
||||||
HRESULT Init(
|
HRESULT Init(
|
||||||
const CArchiveDatabaseEx *archiveDatabase,
|
const CArchiveDatabaseEx *db,
|
||||||
UInt32 ref2Offset, UInt32 startIndex,
|
UInt32 ref2Offset, UInt32 startIndex,
|
||||||
const CBoolVector *extractStatuses,
|
const CBoolVector *extractStatuses,
|
||||||
IArchiveExtractCallback *extractCallback,
|
IArchiveExtractCallback *extractCallback,
|
||||||
|
|||||||
@@ -24,25 +24,20 @@
|
|||||||
|
|
||||||
using namespace NWindows;
|
using namespace NWindows;
|
||||||
|
|
||||||
extern UString ConvertMethodIdToString(UInt64 id);
|
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
CHandler::CHandler()
|
CHandler::CHandler()
|
||||||
{
|
{
|
||||||
_crcSize = 4;
|
|
||||||
|
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
_passwordIsDefined = false;
|
_passwordIsDefined = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTRACT_ONLY
|
#ifdef EXTRACT_ONLY
|
||||||
|
_crcSize = 4;
|
||||||
#ifdef __7Z_SET_PROPERTIES
|
#ifdef __7Z_SET_PROPERTIES
|
||||||
_numThreads = NSystem::GetNumberOfProcessors();
|
_numThreads = NSystem::GetNumberOfProcessors();
|
||||||
#endif
|
#endif
|
||||||
#else
|
|
||||||
Init();
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +65,7 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
STATPROPSTG kArcProps[] =
|
static const STATPROPSTG kArcProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidMethod, VT_BSTR},
|
{ NULL, kpidMethod, VT_BSTR},
|
||||||
{ NULL, kpidSolid, VT_BOOL},
|
{ NULL, kpidSolid, VT_BOOL},
|
||||||
@@ -80,6 +75,25 @@ STATPROPSTG kArcProps[] =
|
|||||||
{ NULL, kpidOffset, VT_UI8}
|
{ NULL, kpidOffset, VT_UI8}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline wchar_t GetHex(Byte value)
|
||||||
|
{
|
||||||
|
return (wchar_t)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static UString ConvertMethodIdToString(UInt64 id)
|
||||||
|
{
|
||||||
|
wchar_t s[32];
|
||||||
|
int len = 32;
|
||||||
|
s[--len] = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
s[--len] = GetHex((Byte)id & 0xF); id >>= 4;
|
||||||
|
s[--len] = GetHex((Byte)id & 0xF); id >>= 4;
|
||||||
|
}
|
||||||
|
while (id != 0);
|
||||||
|
return s + len;
|
||||||
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
@@ -172,22 +186,18 @@ static UString GetStringForSizeValue(UInt32 value)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const UInt64 k_Copy = 0x0;
|
|
||||||
static const UInt64 k_Delta = 3;
|
|
||||||
static const UInt64 k_LZMA2 = 0x21;
|
|
||||||
static const UInt64 k_LZMA = 0x030101;
|
|
||||||
static const UInt64 k_PPMD = 0x030401;
|
|
||||||
|
|
||||||
static wchar_t GetHex(Byte value)
|
|
||||||
{
|
|
||||||
return (wchar_t)((value < 10) ? (L'0' + value) : (L'A' + (value - 10)));
|
|
||||||
}
|
|
||||||
static inline void AddHexToString(UString &res, Byte value)
|
static inline void AddHexToString(UString &res, Byte value)
|
||||||
{
|
{
|
||||||
res += GetHex((Byte)(value >> 4));
|
res += GetHex((Byte)(value >> 4));
|
||||||
res += GetHex((Byte)(value & 0xF));
|
res += GetHex((Byte)(value & 0xF));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void AddProp32(UString &s, const wchar_t *name, UInt32 v)
|
||||||
|
{
|
||||||
|
s += name;
|
||||||
|
s += ConvertUInt32ToString(v);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool CHandler::IsEncrypted(UInt32 index2) const
|
bool CHandler::IsEncrypted(UInt32 index2) const
|
||||||
@@ -283,6 +293,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
{
|
{
|
||||||
UInt32 dicSize = GetUi32((const Byte *)coder.Props + 1);
|
UInt32 dicSize = GetUi32((const Byte *)coder.Props + 1);
|
||||||
propsString = GetStringForSizeValue(dicSize);
|
propsString = GetStringForSizeValue(dicSize);
|
||||||
|
UInt32 d = coder.Props[0];
|
||||||
|
UInt32 lc = d % 9;
|
||||||
|
d /= 9;
|
||||||
|
UInt32 pb = d / 5;
|
||||||
|
UInt32 lp = d % 5;
|
||||||
|
if (lc != 3) AddProp32(propsString, L":lc", lc);
|
||||||
|
if (lp != 0) AddProp32(propsString, L":lp", lp);
|
||||||
|
if (pb != 2) AddProp32(propsString, L":pb", pb);
|
||||||
}
|
}
|
||||||
else if (coder.MethodID == k_LZMA2 && coder.Props.GetCapacity() == 1)
|
else if (coder.MethodID == k_LZMA2 && coder.Props.GetCapacity() == 1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,6 +18,16 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
|
const UInt32 k_Copy = 0x0;
|
||||||
|
const UInt32 k_Delta = 3;
|
||||||
|
const UInt32 k_LZMA2 = 0x21;
|
||||||
|
const UInt32 k_LZMA = 0x030101;
|
||||||
|
const UInt32 k_PPMD = 0x030401;
|
||||||
|
const UInt32 k_BCJ = 0x03030103;
|
||||||
|
const UInt32 k_BCJ2 = 0x0303011B;
|
||||||
|
const UInt32 k_Deflate = 0x040108;
|
||||||
|
const UInt32 k_BZip2 = 0x040202;
|
||||||
|
|
||||||
#ifndef __7Z_SET_PROPERTIES
|
#ifndef __7Z_SET_PROPERTIES
|
||||||
|
|
||||||
#ifdef EXTRACT_ONLY
|
#ifdef EXTRACT_ONLY
|
||||||
@@ -31,9 +41,52 @@ namespace N7z {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef EXTRACT_ONLY
|
||||||
|
|
||||||
|
class COutHandler: public CMultiMethodProps
|
||||||
|
{
|
||||||
|
HRESULT SetSolidFromString(const UString &s);
|
||||||
|
HRESULT SetSolidFromPROPVARIANT(const PROPVARIANT &value);
|
||||||
|
public:
|
||||||
|
bool _removeSfxBlock;
|
||||||
|
|
||||||
|
UInt64 _numSolidFiles;
|
||||||
|
UInt64 _numSolidBytes;
|
||||||
|
bool _numSolidBytesDefined;
|
||||||
|
bool _solidExtension;
|
||||||
|
|
||||||
|
bool _compressHeaders;
|
||||||
|
bool _encryptHeadersSpecified;
|
||||||
|
bool _encryptHeaders;
|
||||||
|
|
||||||
|
bool WriteCTime;
|
||||||
|
bool WriteATime;
|
||||||
|
bool WriteMTime;
|
||||||
|
|
||||||
|
bool _volumeMode;
|
||||||
|
|
||||||
|
void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
|
||||||
|
void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
|
||||||
|
void InitSolid()
|
||||||
|
{
|
||||||
|
InitSolidFiles();
|
||||||
|
InitSolidSize();
|
||||||
|
_solidExtension = false;
|
||||||
|
_numSolidBytesDefined = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitProps();
|
||||||
|
|
||||||
|
COutHandler() { InitProps(); }
|
||||||
|
|
||||||
|
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
class CHandler:
|
class CHandler:
|
||||||
#ifndef EXTRACT_ONLY
|
#ifndef EXTRACT_ONLY
|
||||||
public NArchive::COutHandler,
|
public COutHandler,
|
||||||
#endif
|
#endif
|
||||||
public IInArchive,
|
public IInArchive,
|
||||||
#ifdef __7Z_SET_PROPERTIES
|
#ifdef __7Z_SET_PROPERTIES
|
||||||
@@ -90,16 +143,16 @@ private:
|
|||||||
|
|
||||||
CRecordVector<CBind> _binds;
|
CRecordVector<CBind> _binds;
|
||||||
|
|
||||||
HRESULT SetCompressionMethod(CCompressionMethodMode &method,
|
HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m);
|
||||||
|
HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod);
|
||||||
|
void AddDefaultMethod();
|
||||||
|
HRESULT SetMainMethod(CCompressionMethodMode &method,
|
||||||
CObjectVector<COneMethodInfo> &methodsInfo
|
CObjectVector<COneMethodInfo> &methodsInfo
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
, UInt32 numThreads
|
, UInt32 numThreads
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
HRESULT SetCompressionMethod(
|
|
||||||
CCompressionMethodMode &method,
|
|
||||||
CCompressionMethodMode &headerMethod);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,9 @@
|
|||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "../../../Windows/PropVariant.h"
|
|
||||||
|
|
||||||
#include "../../../Common/ComTry.h"
|
#include "../../../Common/ComTry.h"
|
||||||
#include "../../../Common/StringToInt.h"
|
#include "../../../Common/StringToInt.h"
|
||||||
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
|
|
||||||
#include "../Common/ItemNameUtils.h"
|
#include "../Common/ItemNameUtils.h"
|
||||||
#include "../Common/ParseProperties.h"
|
#include "../Common/ParseProperties.h"
|
||||||
|
|
||||||
@@ -21,24 +17,19 @@ using namespace NWindows;
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
static const wchar_t *kLZMAMethodName = L"LZMA";
|
static const wchar_t *k_LZMA_Name = L"LZMA";
|
||||||
static const wchar_t *kCopyMethod = L"Copy";
|
static const wchar_t *kDefaultMethodName = k_LZMA_Name;
|
||||||
static const wchar_t *kDefaultMethodName = kLZMAMethodName;
|
static const wchar_t *k_Copy_Name = L"Copy";
|
||||||
|
|
||||||
static const UInt32 kLzmaAlgorithmX5 = 1;
|
static const wchar_t *k_MatchFinder_ForHeaders = L"BT2";
|
||||||
static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
|
static const UInt32 k_NumFastBytes_ForHeaders = 273;
|
||||||
static const UInt32 kDictionaryForHeaders =
|
static const UInt32 k_Level_ForHeaders = 5;
|
||||||
|
static const UInt32 k_Dictionary_ForHeaders =
|
||||||
#ifdef UNDER_CE
|
#ifdef UNDER_CE
|
||||||
1 << 18
|
1 << 18;
|
||||||
#else
|
#else
|
||||||
1 << 20
|
1 << 20;
|
||||||
#endif
|
#endif
|
||||||
;
|
|
||||||
static const UInt32 kNumFastBytesForHeaders = 273;
|
|
||||||
static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5;
|
|
||||||
|
|
||||||
static inline bool IsCopyMethod(const UString &methodName)
|
|
||||||
{ return (methodName.CompareNoCase(kCopyMethod) == 0); }
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
|
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
|
||||||
{
|
{
|
||||||
@@ -46,123 +37,105 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CHandler::SetCompressionMethod(
|
HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m)
|
||||||
CCompressionMethodMode &methodMode,
|
|
||||||
CCompressionMethodMode &headerMethod)
|
|
||||||
{
|
{
|
||||||
HRESULT res = SetCompressionMethod(methodMode, _methods
|
if (!FindMethod(
|
||||||
#ifndef _7ZIP_ST
|
EXTERNAL_CODECS_VARS
|
||||||
, _numThreads
|
m.MethodName, dest.Id, dest.NumInStreams, dest.NumOutStreams))
|
||||||
#endif
|
return E_INVALIDARG;
|
||||||
);
|
(CProps &)dest = (CProps &)m;
|
||||||
RINOK(res);
|
|
||||||
methodMode.Binds = _binds;
|
|
||||||
|
|
||||||
if (_compressHeaders)
|
|
||||||
{
|
|
||||||
// headerMethod.Methods.Add(methodMode.Methods.Back());
|
|
||||||
|
|
||||||
CObjectVector<COneMethodInfo> headerMethodInfoVector;
|
|
||||||
COneMethodInfo oneMethodInfo;
|
|
||||||
oneMethodInfo.MethodName = kLZMAMethodName;
|
|
||||||
{
|
|
||||||
CProp prop;
|
|
||||||
prop.Id = NCoderPropID::kMatchFinder;
|
|
||||||
prop.Value = kLzmaMatchFinderForHeaders;
|
|
||||||
oneMethodInfo.Props.Add(prop);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CProp prop;
|
|
||||||
prop.Id = NCoderPropID::kAlgorithm;
|
|
||||||
prop.Value = kAlgorithmForHeaders;
|
|
||||||
oneMethodInfo.Props.Add(prop);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CProp prop;
|
|
||||||
prop.Id = NCoderPropID::kNumFastBytes;
|
|
||||||
prop.Value = (UInt32)kNumFastBytesForHeaders;
|
|
||||||
oneMethodInfo.Props.Add(prop);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CProp prop;
|
|
||||||
prop.Id = NCoderPropID::kDictionarySize;
|
|
||||||
prop.Value = (UInt32)kDictionaryForHeaders;
|
|
||||||
oneMethodInfo.Props.Add(prop);
|
|
||||||
}
|
|
||||||
headerMethodInfoVector.Add(oneMethodInfo);
|
|
||||||
HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector
|
|
||||||
#ifndef _7ZIP_ST
|
|
||||||
, 1
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
RINOK(res);
|
|
||||||
}
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CHandler::SetCompressionMethod(
|
HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod)
|
||||||
|
{
|
||||||
|
if (!_compressHeaders)
|
||||||
|
return S_OK;
|
||||||
|
COneMethodInfo m;
|
||||||
|
m.MethodName = k_LZMA_Name;
|
||||||
|
m.AddPropString(NCoderPropID::kMatchFinder, k_MatchFinder_ForHeaders);
|
||||||
|
m.AddProp32(NCoderPropID::kLevel, k_Level_ForHeaders);
|
||||||
|
m.AddProp32(NCoderPropID::kNumFastBytes, k_NumFastBytes_ForHeaders);
|
||||||
|
m.AddProp32(NCoderPropID::kDictionarySize, k_Dictionary_ForHeaders);
|
||||||
|
m.AddNumThreadsProp(1);
|
||||||
|
|
||||||
|
CMethodFull methodFull;
|
||||||
|
RINOK(PropsMethod_To_FullMethod(methodFull, m));
|
||||||
|
headerMethod.Methods.Add(methodFull);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHandler::AddDefaultMethod()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _methods.Size(); i++)
|
||||||
|
{
|
||||||
|
UString &methodName = _methods[0].MethodName;
|
||||||
|
if (methodName.IsEmpty())
|
||||||
|
methodName = kDefaultMethodName;
|
||||||
|
}
|
||||||
|
if (_methods.IsEmpty())
|
||||||
|
{
|
||||||
|
COneMethodInfo m;
|
||||||
|
m.MethodName = (GetLevel() == 0 ? k_Copy_Name : kDefaultMethodName);
|
||||||
|
_methods.Add(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CHandler::SetMainMethod(
|
||||||
CCompressionMethodMode &methodMode,
|
CCompressionMethodMode &methodMode,
|
||||||
CObjectVector<COneMethodInfo> &methodsInfo
|
CObjectVector<COneMethodInfo> &methods
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
, UInt32 numThreads
|
, UInt32 numThreads
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UInt32 level = _level;
|
AddDefaultMethod();
|
||||||
|
|
||||||
if (methodsInfo.IsEmpty())
|
const UInt64 kSolidBytes_Min = (1 << 24);
|
||||||
{
|
const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1;
|
||||||
COneMethodInfo oneMethodInfo;
|
|
||||||
oneMethodInfo.MethodName = ((level == 0) ? kCopyMethod : kDefaultMethodName);
|
|
||||||
methodsInfo.Add(oneMethodInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool needSolid = false;
|
bool needSolid = false;
|
||||||
for(int i = 0; i < methodsInfo.Size(); i++)
|
for (int i = 0; i < methods.Size(); i++)
|
||||||
{
|
{
|
||||||
COneMethodInfo &oneMethodInfo = methodsInfo[i];
|
COneMethodInfo &oneMethodInfo = methods[i];
|
||||||
SetCompressionMethod2(oneMethodInfo
|
SetGlobalLevelAndThreads(oneMethodInfo
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
, numThreads
|
, numThreads
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!IsCopyMethod(oneMethodInfo.MethodName))
|
|
||||||
needSolid = true;
|
|
||||||
|
|
||||||
CMethodFull methodFull;
|
CMethodFull methodFull;
|
||||||
|
RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
|
||||||
if (!FindMethod(
|
|
||||||
EXTERNAL_CODECS_VARS
|
|
||||||
oneMethodInfo.MethodName, methodFull.Id, methodFull.NumInStreams, methodFull.NumOutStreams))
|
|
||||||
return E_INVALIDARG;
|
|
||||||
methodFull.Props = oneMethodInfo.Props;
|
|
||||||
methodMode.Methods.Add(methodFull);
|
methodMode.Methods.Add(methodFull);
|
||||||
|
|
||||||
if (!_numSolidBytesDefined)
|
if (methodFull.Id != k_Copy)
|
||||||
|
needSolid = true;
|
||||||
|
|
||||||
|
if (_numSolidBytesDefined)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
UInt32 dicSize;
|
||||||
|
switch (methodFull.Id)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < methodFull.Props.Size(); j++)
|
case k_LZMA:
|
||||||
{
|
case k_LZMA2: dicSize = oneMethodInfo.Get_Lzma_DicSize(); break;
|
||||||
const CProp &prop = methodFull.Props[j];
|
case k_PPMD: dicSize = oneMethodInfo.Get_Ppmd_MemSize(); break;
|
||||||
if ((prop.Id == NCoderPropID::kDictionarySize ||
|
case k_Deflate: dicSize = (UInt32)1 << 15; break;
|
||||||
prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4)
|
case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break;
|
||||||
{
|
default: continue;
|
||||||
_numSolidBytes = ((UInt64)prop.Value.ulVal) << 7;
|
|
||||||
const UInt64 kMinSize = (1 << 24);
|
|
||||||
if (_numSolidBytes < kMinSize)
|
|
||||||
_numSolidBytes = kMinSize;
|
|
||||||
_numSolidBytesDefined = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
_numSolidBytes = (UInt64)dicSize << 7;
|
||||||
|
if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min;
|
||||||
|
if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max;
|
||||||
|
_numSolidBytesDefined = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!needSolid && !_numSolidBytesDefined)
|
if (!_numSolidBytesDefined)
|
||||||
{
|
if (needSolid)
|
||||||
_numSolidBytesDefined = true;
|
_numSolidBytes = kSolidBytes_Max;
|
||||||
_numSolidBytes = 0;
|
else
|
||||||
}
|
_numSolidBytes = 0;
|
||||||
|
_numSolidBytesDefined = true;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,7 +299,16 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
}
|
}
|
||||||
|
|
||||||
CCompressionMethodMode methodMode, headerMethod;
|
CCompressionMethodMode methodMode, headerMethod;
|
||||||
RINOK(SetCompressionMethod(methodMode, headerMethod));
|
|
||||||
|
HRESULT res = SetMainMethod(methodMode, _methods
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
, _numThreads
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
RINOK(res);
|
||||||
|
methodMode.Binds = _binds;
|
||||||
|
|
||||||
|
RINOK(SetHeaderMethod(headerMethod));
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
methodMode.NumThreads = _numThreads;
|
methodMode.NumThreads = _numThreads;
|
||||||
headerMethod.NumThreads = 1;
|
headerMethod.NumThreads = 1;
|
||||||
@@ -373,8 +355,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
CUpdateOptions options;
|
CUpdateOptions options;
|
||||||
options.Method = &methodMode;
|
options.Method = &methodMode;
|
||||||
options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0;
|
options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0;
|
||||||
options.UseFilters = _level != 0 && _autoFilter;
|
int level = GetLevel();
|
||||||
options.MaxFilter = _level >= 8;
|
options.UseFilters = level != 0 && _autoFilter;
|
||||||
|
options.MaxFilter = level >= 8;
|
||||||
|
|
||||||
options.HeaderOptions.CompressMainHeader = compressMainHeader;
|
options.HeaderOptions.CompressMainHeader = compressMainHeader;
|
||||||
options.HeaderOptions.WriteCTime = WriteCTime;
|
options.HeaderOptions.WriteCTime = WriteCTime;
|
||||||
@@ -393,7 +376,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
CMyComPtr<ICryptoGetTextPassword> getPassword;
|
CMyComPtr<ICryptoGetTextPassword> getPassword;
|
||||||
updateCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getPassword);
|
updateCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getPassword);
|
||||||
|
|
||||||
HRESULT res = Update(
|
res = Update(
|
||||||
EXTERNAL_CODECS_VARS
|
EXTERNAL_CODECS_VARS
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
volume ? volume->Stream: 0,
|
volume ? volume->Stream: 0,
|
||||||
@@ -437,25 +420,138 @@ static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT GetBindInfo(UString &srcString, CBind &bind)
|
void COutHandler::InitProps()
|
||||||
{
|
{
|
||||||
RINOK(GetBindInfoPart(srcString, bind.OutCoder, bind.OutStream));
|
CMultiMethodProps::Init();
|
||||||
if (srcString[0] != ':')
|
|
||||||
return E_INVALIDARG;
|
_removeSfxBlock = false;
|
||||||
srcString.Delete(0);
|
_compressHeaders = true;
|
||||||
RINOK(GetBindInfoPart(srcString, bind.InCoder, bind.InStream));
|
_encryptHeadersSpecified = false;
|
||||||
if (!srcString.IsEmpty())
|
_encryptHeaders = false;
|
||||||
return E_INVALIDARG;
|
|
||||||
|
WriteCTime = false;
|
||||||
|
WriteATime = false;
|
||||||
|
WriteMTime = true;
|
||||||
|
|
||||||
|
_volumeMode = false;
|
||||||
|
InitSolid();
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT COutHandler::SetSolidFromString(const UString &s)
|
||||||
|
{
|
||||||
|
UString s2 = s;
|
||||||
|
s2.MakeUpper();
|
||||||
|
for (int i = 0; i < s2.Length();)
|
||||||
|
{
|
||||||
|
const wchar_t *start = ((const wchar_t *)s2) + i;
|
||||||
|
const wchar_t *end;
|
||||||
|
UInt64 v = ConvertStringToUInt64(start, &end);
|
||||||
|
if (start == end)
|
||||||
|
{
|
||||||
|
if (s2[i++] != 'E')
|
||||||
|
return E_INVALIDARG;
|
||||||
|
_solidExtension = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
i += (int)(end - start);
|
||||||
|
if (i == s2.Length())
|
||||||
|
return E_INVALIDARG;
|
||||||
|
wchar_t c = s2[i++];
|
||||||
|
if (c == 'F')
|
||||||
|
{
|
||||||
|
if (v < 1)
|
||||||
|
v = 1;
|
||||||
|
_numSolidFiles = v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned numBits;
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'B': numBits = 0; break;
|
||||||
|
case 'K': numBits = 10; break;
|
||||||
|
case 'M': numBits = 20; break;
|
||||||
|
case 'G': numBits = 30; break;
|
||||||
|
default: return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
_numSolidBytes = (v << numBits);
|
||||||
|
_numSolidBytesDefined = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
|
HRESULT COutHandler::SetSolidFromPROPVARIANT(const PROPVARIANT &value)
|
||||||
|
{
|
||||||
|
bool isSolid;
|
||||||
|
switch (value.vt)
|
||||||
|
{
|
||||||
|
case VT_EMPTY: isSolid = true; break;
|
||||||
|
case VT_BOOL: isSolid = (value.boolVal != VARIANT_FALSE); break;
|
||||||
|
case VT_BSTR:
|
||||||
|
if (StringToBool(value.bstrVal, isSolid))
|
||||||
|
break;
|
||||||
|
return SetSolidFromString(value.bstrVal);
|
||||||
|
default: return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
if (isSolid)
|
||||||
|
InitSolid();
|
||||||
|
else
|
||||||
|
_numSolidFiles = 1;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
|
||||||
|
{
|
||||||
|
UString name = nameSpec;
|
||||||
|
name.MakeUpper();
|
||||||
|
if (name.IsEmpty())
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (name[0] == L'S')
|
||||||
|
{
|
||||||
|
name.Delete(0);
|
||||||
|
if (name.IsEmpty())
|
||||||
|
return SetSolidFromPROPVARIANT(value);
|
||||||
|
if (value.vt != VT_EMPTY)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
return SetSolidFromString(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 number;
|
||||||
|
int index = ParseStringToUInt32(name, number);
|
||||||
|
UString realName = name.Mid(index);
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
|
if (name.CompareNoCase(L"RSFX") == 0) return PROPVARIANT_to_bool(value, _removeSfxBlock);
|
||||||
|
if (name.CompareNoCase(L"HC") == 0) return PROPVARIANT_to_bool(value, _compressHeaders);
|
||||||
|
if (name.CompareNoCase(L"HCF") == 0)
|
||||||
|
{
|
||||||
|
bool compressHeadersFull = true;
|
||||||
|
RINOK(PROPVARIANT_to_bool(value, compressHeadersFull));
|
||||||
|
return compressHeadersFull ? S_OK: E_INVALIDARG;
|
||||||
|
}
|
||||||
|
if (name.CompareNoCase(L"HE") == 0)
|
||||||
|
{
|
||||||
|
RINOK(PROPVARIANT_to_bool(value, _encryptHeaders));
|
||||||
|
_encryptHeadersSpecified = true;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
if (name.CompareNoCase(L"TC") == 0) return PROPVARIANT_to_bool(value, WriteCTime);
|
||||||
|
if (name.CompareNoCase(L"TA") == 0) return PROPVARIANT_to_bool(value, WriteATime);
|
||||||
|
if (name.CompareNoCase(L"TM") == 0) return PROPVARIANT_to_bool(value, WriteMTime);
|
||||||
|
if (name.CompareNoCase(L"V") == 0) return PROPVARIANT_to_bool(value, _volumeMode);
|
||||||
|
}
|
||||||
|
return CMultiMethodProps::SetProperty(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
_binds.Clear();
|
_binds.Clear();
|
||||||
BeforeSetProperty();
|
InitProps();
|
||||||
|
|
||||||
for (int i = 0; i < numProperties; i++)
|
for (int i = 0; i < numProps; i++)
|
||||||
{
|
{
|
||||||
UString name = names[i];
|
UString name = names[i];
|
||||||
name.MakeUpper();
|
name.MakeUpper();
|
||||||
@@ -466,9 +562,17 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
|||||||
|
|
||||||
if (name[0] == 'B')
|
if (name[0] == 'B')
|
||||||
{
|
{
|
||||||
|
if (value.vt != VT_EMPTY)
|
||||||
|
return E_INVALIDARG;
|
||||||
name.Delete(0);
|
name.Delete(0);
|
||||||
CBind bind;
|
CBind bind;
|
||||||
RINOK(GetBindInfo(name, bind));
|
RINOK(GetBindInfoPart(name, bind.OutCoder, bind.OutStream));
|
||||||
|
if (name[0] != ':')
|
||||||
|
return E_INVALIDARG;
|
||||||
|
name.Delete(0);
|
||||||
|
RINOK(GetBindInfoPart(name, bind.InCoder, bind.InStream));
|
||||||
|
if (!name.IsEmpty())
|
||||||
|
return E_INVALIDARG;
|
||||||
_binds.Add(bind);
|
_binds.Add(bind);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -476,6 +580,47 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
|||||||
RINOK(SetProperty(name, value));
|
RINOK(SetProperty(name, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int numEmptyMethods = GetNumEmptyMethods();
|
||||||
|
if (numEmptyMethods > 0)
|
||||||
|
{
|
||||||
|
int k;
|
||||||
|
for (k = 0; k < _binds.Size(); k++)
|
||||||
|
{
|
||||||
|
const CBind &bind = _binds[k];
|
||||||
|
if (bind.InCoder < (UInt32)numEmptyMethods ||
|
||||||
|
bind.OutCoder < (UInt32)numEmptyMethods)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
for (k = 0; k < _binds.Size(); k++)
|
||||||
|
{
|
||||||
|
CBind &bind = _binds[k];
|
||||||
|
bind.InCoder -= (UInt32)numEmptyMethods;
|
||||||
|
bind.OutCoder -= (UInt32)numEmptyMethods;
|
||||||
|
}
|
||||||
|
_methods.Delete(0, numEmptyMethods);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddDefaultMethod();
|
||||||
|
|
||||||
|
if (!_filterMethod.MethodName.IsEmpty())
|
||||||
|
{
|
||||||
|
for (int k = 0; k < _binds.Size(); k++)
|
||||||
|
{
|
||||||
|
CBind &bind = _binds[k];
|
||||||
|
bind.InCoder++;
|
||||||
|
bind.OutCoder++;
|
||||||
|
}
|
||||||
|
_methods.Insert(0, _filterMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int k = 0; k < _binds.Size(); k++)
|
||||||
|
{
|
||||||
|
const CBind &bind = _binds[k];
|
||||||
|
if (bind.InCoder >= (UInt32)_methods.Size() ||
|
||||||
|
bind.OutCoder >= (UInt32)_methods.Size())
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ public:
|
|||||||
kUnsupportedVersion = 0,
|
kUnsupportedVersion = 0,
|
||||||
kUnsupported,
|
kUnsupported,
|
||||||
kIncorrect,
|
kIncorrect,
|
||||||
kEndOfData,
|
kEndOfData
|
||||||
} Cause;
|
} Cause;
|
||||||
CInArchiveException(CCauseType cause): Cause(cause) {};
|
CInArchiveException(CCauseType cause): Cause(cause) {};
|
||||||
};
|
};
|
||||||
@@ -280,50 +280,60 @@ void CInByte2::ReadString(UString &s)
|
|||||||
_pos += rem + 2;
|
_pos += rem + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool TestSignatureCandidate(const Byte *p)
|
static inline bool TestSignature(const Byte *p)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < kSignatureSize; i++)
|
for (int i = 0; i < kSignatureSize; i++)
|
||||||
if (p[i] != kSignature[i])
|
if (p[i] != kSignature[i])
|
||||||
return false;
|
return false;
|
||||||
return (p[0x1A] == 0 && p[0x1B] == 0);
|
return CrcCalc(p + 12, 20) == GetUi32(p + 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef FORMAT_7Z_RECOVERY
|
||||||
|
static inline bool TestSignature2(const Byte *p)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < kSignatureSize; i++)
|
||||||
|
if (p[i] != kSignature[i])
|
||||||
|
return false;
|
||||||
|
if (CrcCalc(p + 12, 20) == GetUi32(p + 8))
|
||||||
|
return true;
|
||||||
|
for (i = 8; i < kHeaderSize; i++)
|
||||||
|
if (p[i] != 0)
|
||||||
|
return false;
|
||||||
|
return (p[6] != 0 || p[7] != 0);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define TestSignature2(p) TestSignature(p)
|
||||||
|
#endif
|
||||||
|
|
||||||
HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
|
HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
|
||||||
{
|
{
|
||||||
RINOK(ReadStream_FALSE(stream, _header, kHeaderSize));
|
RINOK(ReadStream_FALSE(stream, _header, kHeaderSize));
|
||||||
|
|
||||||
if (TestSignatureCandidate(_header))
|
if (TestSignature2(_header))
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
CByteBuffer byteBuffer;
|
CByteBuffer byteBuffer;
|
||||||
const UInt32 kBufferSize = (1 << 16);
|
const UInt32 kBufferSize = (1 << 16);
|
||||||
byteBuffer.SetCapacity(kBufferSize);
|
byteBuffer.SetCapacity(kBufferSize);
|
||||||
Byte *buffer = byteBuffer;
|
Byte *buffer = byteBuffer;
|
||||||
UInt32 numPrevBytes = kHeaderSize - 1;
|
memcpy(buffer, _header, kHeaderSize);
|
||||||
memcpy(buffer, _header + 1, numPrevBytes);
|
UInt64 curTestPos = _arhiveBeginStreamPosition;
|
||||||
UInt64 curTestPos = _arhiveBeginStreamPosition + 1;
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (searchHeaderSizeLimit != NULL)
|
if (searchHeaderSizeLimit != NULL)
|
||||||
if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
|
if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
|
||||||
break;
|
break;
|
||||||
do
|
UInt32 processedSize;
|
||||||
|
RINOK(stream->Read(buffer + kHeaderSize, kBufferSize - kHeaderSize, &processedSize));
|
||||||
|
if (processedSize == 0)
|
||||||
|
return S_FALSE;
|
||||||
|
for (UInt32 pos = 1; pos <= processedSize; pos++)
|
||||||
{
|
{
|
||||||
UInt32 numReadBytes = kBufferSize - numPrevBytes;
|
for (; buffer[pos] != '7' && pos <= processedSize; pos++);
|
||||||
UInt32 processedSize;
|
if (pos > processedSize)
|
||||||
RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
|
|
||||||
numPrevBytes += processedSize;
|
|
||||||
if (processedSize == 0)
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
while (numPrevBytes < kHeaderSize);
|
|
||||||
UInt32 numTests = numPrevBytes - kHeaderSize + 1;
|
|
||||||
for (UInt32 pos = 0; pos < numTests; pos++)
|
|
||||||
{
|
|
||||||
for (; buffer[pos] != '7' && pos < numTests; pos++);
|
|
||||||
if (pos == numTests)
|
|
||||||
break;
|
break;
|
||||||
if (TestSignatureCandidate(buffer + pos))
|
if (TestSignature(buffer + pos))
|
||||||
{
|
{
|
||||||
memcpy(_header, buffer + pos, kHeaderSize);
|
memcpy(_header, buffer + pos, kHeaderSize);
|
||||||
curTestPos += pos;
|
curTestPos += pos;
|
||||||
@@ -331,9 +341,8 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
|
|||||||
return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL);
|
return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
curTestPos += numTests;
|
curTestPos += processedSize;
|
||||||
numPrevBytes -= numTests;
|
memmove(buffer, buffer + processedSize, kHeaderSize);
|
||||||
memmove(buffer, buffer + numTests, numPrevBytes);
|
|
||||||
}
|
}
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
@@ -344,6 +353,8 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
|
|||||||
HeadersSize = 0;
|
HeadersSize = 0;
|
||||||
Close();
|
Close();
|
||||||
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
|
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
|
||||||
|
RINOK(stream->Seek(0, STREAM_SEEK_END, &_fileEndPosition))
|
||||||
|
RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL))
|
||||||
RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
|
RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
|
||||||
_stream = stream;
|
_stream = stream;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@@ -812,7 +823,7 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
|||||||
ThrowUnsupported();
|
ThrowUnsupported();
|
||||||
data.SetCapacity(unpackSize);
|
data.SetCapacity(unpackSize);
|
||||||
|
|
||||||
CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2;
|
CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream;
|
||||||
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
|
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
|
||||||
outStreamSpec->Init(data, unpackSize);
|
outStreamSpec->Init(data, unpackSize);
|
||||||
|
|
||||||
@@ -1164,23 +1175,26 @@ HRESULT CInArchive::ReadDatabase2(
|
|||||||
nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);
|
nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);
|
||||||
RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));
|
RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
#ifdef FORMAT_7Z_RECOVERY
|
if (crc != crcFromArchive)
|
||||||
crcFromArchive = crc;
|
ThrowIncorrect();
|
||||||
#endif
|
}
|
||||||
|
|
||||||
db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
|
db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
|
||||||
|
|
||||||
if (crc != crcFromArchive)
|
|
||||||
ThrowIncorrect();
|
|
||||||
|
|
||||||
if (nextHeaderSize == 0)
|
if (nextHeaderSize == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
if (nextHeaderSize > (UInt64)0xFFFFFFFF)
|
if (nextHeaderSize > (UInt64)(UInt32)0xFFFFFFFF)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
|
if ((Int64)nextHeaderOffset < 0)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
if (db.ArchiveInfo.StartPositionAfterHeader + nextHeaderOffset > _fileEndPosition)
|
||||||
|
return S_FALSE;
|
||||||
RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL));
|
RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL));
|
||||||
|
|
||||||
CByteBuffer buffer2;
|
CByteBuffer buffer2;
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ class CInArchive
|
|||||||
CInByte2 *_inByteBack;
|
CInByte2 *_inByteBack;
|
||||||
|
|
||||||
UInt64 _arhiveBeginStreamPosition;
|
UInt64 _arhiveBeginStreamPosition;
|
||||||
|
UInt64 _fileEndPosition;
|
||||||
|
|
||||||
Byte _header[kHeaderSize];
|
Byte _header[kHeaderSize];
|
||||||
|
|
||||||
|
|||||||
@@ -19,32 +19,33 @@ struct CPropMap
|
|||||||
|
|
||||||
CPropMap kPropMap[] =
|
CPropMap kPropMap[] =
|
||||||
{
|
{
|
||||||
{ NID::kName, NULL, kpidPath, VT_BSTR},
|
{ NID::kName, { NULL, kpidPath, VT_BSTR } },
|
||||||
{ NID::kSize, NULL, kpidSize, VT_UI8},
|
{ NID::kSize, { NULL, kpidSize, VT_UI8 } },
|
||||||
{ NID::kPackInfo, NULL, kpidPackSize, VT_UI8},
|
{ NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } },
|
||||||
|
|
||||||
#ifdef _MULTI_PACK
|
#ifdef _MULTI_PACK
|
||||||
{ 100, L"Pack0", kpidPackedSize0, VT_UI8},
|
{ 100, { L"Pack0", kpidPackedSize0, VT_UI8 } },
|
||||||
{ 101, L"Pack1", kpidPackedSize1, VT_UI8},
|
{ 101, { L"Pack1", kpidPackedSize1, VT_UI8 } },
|
||||||
{ 102, L"Pack2", kpidPackedSize2, VT_UI8},
|
{ 102, { L"Pack2", kpidPackedSize2, VT_UI8 } },
|
||||||
{ 103, L"Pack3", kpidPackedSize3, VT_UI8},
|
{ 103, { L"Pack3", kpidPackedSize3, VT_UI8 } },
|
||||||
{ 104, L"Pack4", kpidPackedSize4, VT_UI8},
|
{ 104, { L"Pack4", kpidPackedSize4, VT_UI8 } },
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{ NID::kCTime, NULL, kpidCTime, VT_FILETIME},
|
{ NID::kCTime, { NULL, kpidCTime, VT_FILETIME } },
|
||||||
{ NID::kMTime, NULL, kpidMTime, VT_FILETIME},
|
{ NID::kMTime, { NULL, kpidMTime, VT_FILETIME } },
|
||||||
{ NID::kATime, NULL, kpidATime, VT_FILETIME},
|
{ NID::kATime, { NULL, kpidATime, VT_FILETIME } },
|
||||||
{ NID::kWinAttributes, NULL, kpidAttrib, VT_UI4},
|
{ NID::kWinAttributes, { NULL, kpidAttrib, VT_UI4 } },
|
||||||
{ NID::kStartPos, NULL, kpidPosition, VT_UI4},
|
{ NID::kStartPos, { NULL, kpidPosition, VT_UI4 } },
|
||||||
|
|
||||||
{ NID::kCRC, NULL, kpidCRC, VT_UI4},
|
{ NID::kCRC, { NULL, kpidCRC, VT_UI4 } },
|
||||||
|
|
||||||
{ NID::kAnti, NULL, kpidIsAnti, VT_BOOL},
|
{ NID::kAnti, { NULL, kpidIsAnti, VT_BOOL } }
|
||||||
|
|
||||||
#ifndef _SFX
|
#ifndef _SFX
|
||||||
{ 97, NULL, kpidEncrypted, VT_BOOL},
|
,
|
||||||
{ 98, NULL, kpidMethod, VT_BSTR},
|
{ 97, { NULL,kpidEncrypted, VT_BOOL } },
|
||||||
{ 99, NULL, kpidBlock, VT_UI4}
|
{ 98, { NULL,kpidMethod, VT_BSTR } },
|
||||||
|
{ 99, { NULL,kpidBlock, VT_UI4 } }
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -24,15 +24,6 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
static const UInt64 k_LZMA = 0x030101;
|
|
||||||
static const UInt64 k_BCJ = 0x03030103;
|
|
||||||
static const UInt64 k_BCJ2 = 0x0303011B;
|
|
||||||
|
|
||||||
static const wchar_t *kMatchFinderForBCJ2_LZMA = L"BT2";
|
|
||||||
static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;
|
|
||||||
static const UInt32 kAlgorithmForBCJ2_LZMA = 1;
|
|
||||||
static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
|
|
||||||
|
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
#define USE_86_FILTER
|
#define USE_86_FILTER
|
||||||
#endif
|
#endif
|
||||||
@@ -339,90 +330,74 @@ static bool IsExeExt(const UString &ext)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_86_FILTER
|
|
||||||
|
|
||||||
static inline void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &methodResult)
|
static inline void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &m)
|
||||||
{
|
{
|
||||||
methodResult.Id = methodID;
|
m.Id = methodID;
|
||||||
methodResult.NumInStreams = numInStreams;
|
m.NumInStreams = numInStreams;
|
||||||
methodResult.NumOutStreams = 1;
|
m.NumOutStreams = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MakeExeMethod(const CCompressionMethodMode &method,
|
static void AddBcj2Methods(CCompressionMethodMode &mode)
|
||||||
bool bcj2Filter, CCompressionMethodMode &exeMethod)
|
|
||||||
{
|
{
|
||||||
exeMethod = method;
|
CMethodFull m;
|
||||||
|
GetMethodFull(k_LZMA, 1, m);
|
||||||
|
|
||||||
|
m.AddProp32(NCoderPropID::kDictionarySize, 1 << 20);
|
||||||
|
m.AddProp32(NCoderPropID::kNumFastBytes, 128);
|
||||||
|
m.AddProp32(NCoderPropID::kNumThreads, 1);
|
||||||
|
m.AddProp32(NCoderPropID::kLitPosBits, 2);
|
||||||
|
m.AddProp32(NCoderPropID::kLitContextBits, 0);
|
||||||
|
// m.AddPropString(NCoderPropID::kMatchFinder, L"BT2");
|
||||||
|
|
||||||
|
mode.Methods.Add(m);
|
||||||
|
mode.Methods.Add(m);
|
||||||
|
|
||||||
|
CBind bind;
|
||||||
|
bind.OutCoder = 0;
|
||||||
|
bind.InStream = 0;
|
||||||
|
bind.InCoder = 1; bind.OutStream = 0; mode.Binds.Add(bind);
|
||||||
|
bind.InCoder = 2; bind.OutStream = 1; mode.Binds.Add(bind);
|
||||||
|
bind.InCoder = 3; bind.OutStream = 2; mode.Binds.Add(bind);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MakeExeMethod(CCompressionMethodMode &mode,
|
||||||
|
bool useFilters, bool addFilter, bool bcj2Filter)
|
||||||
|
{
|
||||||
|
if (!mode.Binds.IsEmpty() || !useFilters || mode.Methods.Size() > 2)
|
||||||
|
return;
|
||||||
|
if (mode.Methods.Size() == 2)
|
||||||
|
{
|
||||||
|
if (mode.Methods[0].Id == k_BCJ2)
|
||||||
|
AddBcj2Methods(mode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!addFilter)
|
||||||
|
return;
|
||||||
|
bcj2Filter = bcj2Filter;
|
||||||
|
#ifdef USE_86_FILTER
|
||||||
if (bcj2Filter)
|
if (bcj2Filter)
|
||||||
{
|
{
|
||||||
CMethodFull methodFull;
|
CMethodFull m;
|
||||||
GetMethodFull(k_BCJ2, 4, methodFull);
|
GetMethodFull(k_BCJ2, 4, m);
|
||||||
exeMethod.Methods.Insert(0, methodFull);
|
mode.Methods.Insert(0, m);
|
||||||
GetMethodFull(k_LZMA, 1, methodFull);
|
AddBcj2Methods(mode);
|
||||||
{
|
|
||||||
CProp prop;
|
|
||||||
prop.Id = NCoderPropID::kAlgorithm;
|
|
||||||
prop.Value = kAlgorithmForBCJ2_LZMA;
|
|
||||||
methodFull.Props.Add(prop);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CProp prop;
|
|
||||||
prop.Id = NCoderPropID::kMatchFinder;
|
|
||||||
prop.Value = kMatchFinderForBCJ2_LZMA;
|
|
||||||
methodFull.Props.Add(prop);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CProp prop;
|
|
||||||
prop.Id = NCoderPropID::kDictionarySize;
|
|
||||||
prop.Value = kDictionaryForBCJ2_LZMA;
|
|
||||||
methodFull.Props.Add(prop);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CProp prop;
|
|
||||||
prop.Id = NCoderPropID::kNumFastBytes;
|
|
||||||
prop.Value = kNumFastBytesForBCJ2_LZMA;
|
|
||||||
methodFull.Props.Add(prop);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
CProp prop;
|
|
||||||
prop.Id = NCoderPropID::kNumThreads;
|
|
||||||
prop.Value = (UInt32)1;
|
|
||||||
methodFull.Props.Add(prop);
|
|
||||||
}
|
|
||||||
|
|
||||||
exeMethod.Methods.Add(methodFull);
|
|
||||||
exeMethod.Methods.Add(methodFull);
|
|
||||||
CBind bind;
|
|
||||||
|
|
||||||
bind.OutCoder = 0;
|
|
||||||
bind.InStream = 0;
|
|
||||||
|
|
||||||
bind.InCoder = 1;
|
|
||||||
bind.OutStream = 0;
|
|
||||||
exeMethod.Binds.Add(bind);
|
|
||||||
|
|
||||||
bind.InCoder = 2;
|
|
||||||
bind.OutStream = 1;
|
|
||||||
exeMethod.Binds.Add(bind);
|
|
||||||
|
|
||||||
bind.InCoder = 3;
|
|
||||||
bind.OutStream = 2;
|
|
||||||
exeMethod.Binds.Add(bind);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CMethodFull methodFull;
|
CMethodFull m;
|
||||||
GetMethodFull(k_BCJ, 1, methodFull);
|
GetMethodFull(k_BCJ, 1, m);
|
||||||
exeMethod.Methods.Insert(0, methodFull);
|
mode.Methods.Insert(0, m);
|
||||||
CBind bind;
|
CBind bind;
|
||||||
bind.OutCoder = 0;
|
bind.OutCoder = 0;
|
||||||
bind.InStream = 0;
|
bind.InStream = 0;
|
||||||
bind.InCoder = 1;
|
bind.InCoder = 1;
|
||||||
bind.OutStream = 0;
|
bind.OutStream = 0;
|
||||||
exeMethod.Binds.Add(bind);
|
mode.Binds.Add(bind);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void FromUpdateItemToFileItem(const CUpdateItem &ui,
|
static void FromUpdateItemToFileItem(const CUpdateItem &ui,
|
||||||
CFileItem &file, CFileItem2 &file2)
|
CFileItem &file, CFileItem2 &file2)
|
||||||
@@ -601,6 +576,7 @@ public:
|
|||||||
Fos = FosSpec;
|
Fos = FosSpec;
|
||||||
Result = E_FAIL;
|
Result = E_FAIL;
|
||||||
}
|
}
|
||||||
|
~CThreadDecoder() { CVirtThread::WaitThreadFinish(); }
|
||||||
virtual void Execute();
|
virtual void Execute();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -669,9 +645,7 @@ STDMETHODIMP CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password)
|
|||||||
|
|
||||||
static const int kNumGroupsMax = 4;
|
static const int kNumGroupsMax = 4;
|
||||||
|
|
||||||
#ifdef USE_86_FILTER
|
|
||||||
static bool Is86Group(int group) { return (group & 1) != 0; }
|
static bool Is86Group(int group) { return (group & 1) != 0; }
|
||||||
#endif
|
|
||||||
static bool IsEncryptedGroup(int group) { return (group & 2) != 0; }
|
static bool IsEncryptedGroup(int group) { return (group & 2) != 0; }
|
||||||
static int GetGroupIndex(bool encrypted, int bcjFiltered)
|
static int GetGroupIndex(bool encrypted, int bcjFiltered)
|
||||||
{ return (encrypted ? 2 : 0) + (bcjFiltered ? 1 : 0); }
|
{ return (encrypted ? 2 : 0) + (bcjFiltered ? 1 : 0); }
|
||||||
@@ -789,16 +763,15 @@ HRESULT Update(
|
|||||||
if (inSizeForReduce2 > inSizeForReduce)
|
if (inSizeForReduce2 > inSizeForReduce)
|
||||||
inSizeForReduce = inSizeForReduce2;
|
inSizeForReduce = inSizeForReduce2;
|
||||||
|
|
||||||
const UInt32 kMinReduceSize = (1 << 16);
|
|
||||||
if (inSizeForReduce < kMinReduceSize)
|
|
||||||
inSizeForReduce = kMinReduceSize;
|
|
||||||
|
|
||||||
RINOK(updateCallback->SetTotal(complexity));
|
RINOK(updateCallback->SetTotal(complexity));
|
||||||
|
|
||||||
CLocalProgress *lps = new CLocalProgress;
|
CLocalProgress *lps = new CLocalProgress;
|
||||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||||
lps->Init(updateCallback, true);
|
lps->Init(updateCallback, true);
|
||||||
|
|
||||||
|
CStreamBinder sb;
|
||||||
|
RINOK(sb.CreateEvents());
|
||||||
|
|
||||||
CThreadDecoder threadDecoder;
|
CThreadDecoder threadDecoder;
|
||||||
if (!folderRefs.IsEmpty())
|
if (!folderRefs.IsEmpty())
|
||||||
{
|
{
|
||||||
@@ -870,13 +843,8 @@ HRESULT Update(
|
|||||||
{
|
{
|
||||||
const CSolidGroup &group = groups[groupIndex];
|
const CSolidGroup &group = groups[groupIndex];
|
||||||
|
|
||||||
CCompressionMethodMode method;
|
CCompressionMethodMode method = *options.Method;
|
||||||
#ifdef USE_86_FILTER
|
MakeExeMethod(method, options.UseFilters, Is86Group(groupIndex), options.MaxFilter);
|
||||||
if (Is86Group(groupIndex))
|
|
||||||
MakeExeMethod(*options.Method, options.MaxFilter, method);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
method = *options.Method;
|
|
||||||
|
|
||||||
if (IsEncryptedGroup(groupIndex))
|
if (IsEncryptedGroup(groupIndex))
|
||||||
{
|
{
|
||||||
@@ -923,11 +891,6 @@ HRESULT Update(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CStreamBinder sb;
|
|
||||||
RINOK(sb.CreateEvents());
|
|
||||||
CMyComPtr<ISequentialOutStream> sbOutStream;
|
|
||||||
CMyComPtr<ISequentialInStream> sbInStream;
|
|
||||||
sb.CreateStreams(&sbInStream, &sbOutStream);
|
|
||||||
CBoolVector extractStatuses;
|
CBoolVector extractStatuses;
|
||||||
|
|
||||||
CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];
|
CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];
|
||||||
@@ -946,24 +909,31 @@ HRESULT Update(
|
|||||||
extractStatuses.Add(needExtract);
|
extractStatuses.Add(needExtract);
|
||||||
}
|
}
|
||||||
|
|
||||||
RINOK(threadDecoder.FosSpec->Init(db, db->FolderStartFileIndex[folderIndex], &extractStatuses, sbOutStream));
|
|
||||||
sbOutStream.Release();
|
|
||||||
|
|
||||||
threadDecoder.InStream = inStream;
|
|
||||||
threadDecoder.Folder = &db->Folders[folderIndex];
|
|
||||||
threadDecoder.StartPos = db->GetFolderStreamPos(folderIndex, 0);
|
|
||||||
threadDecoder.PackSizes = &db->PackSizes[db->FolderStartPackStreamIndex[folderIndex]];
|
|
||||||
|
|
||||||
threadDecoder.Start();
|
|
||||||
|
|
||||||
int startPackIndex = newDatabase.PackSizes.Size();
|
int startPackIndex = newDatabase.PackSizes.Size();
|
||||||
CFolder newFolder;
|
CFolder newFolder;
|
||||||
RINOK(encoder.Encode(
|
{
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
CMyComPtr<ISequentialInStream> sbInStream;
|
||||||
sbInStream, NULL, &inSizeForReduce, newFolder,
|
{
|
||||||
archive.SeqStream, newDatabase.PackSizes, progress));
|
CMyComPtr<ISequentialOutStream> sbOutStream;
|
||||||
|
sb.CreateStreams(&sbInStream, &sbOutStream);
|
||||||
threadDecoder.WaitFinish();
|
sb.ReInit();
|
||||||
|
RINOK(threadDecoder.FosSpec->Init(db, db->FolderStartFileIndex[folderIndex], &extractStatuses, sbOutStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
threadDecoder.InStream = inStream;
|
||||||
|
threadDecoder.Folder = &db->Folders[folderIndex];
|
||||||
|
threadDecoder.StartPos = db->GetFolderStreamPos(folderIndex, 0);
|
||||||
|
threadDecoder.PackSizes = &db->PackSizes[db->FolderStartPackStreamIndex[folderIndex]];
|
||||||
|
|
||||||
|
threadDecoder.Start();
|
||||||
|
|
||||||
|
RINOK(encoder.Encode(
|
||||||
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
|
sbInStream, NULL, &inSizeForReduce, newFolder,
|
||||||
|
archive.SeqStream, newDatabase.PackSizes, progress));
|
||||||
|
|
||||||
|
threadDecoder.WaitExecuteFinish();
|
||||||
|
}
|
||||||
|
|
||||||
RINOK(threadDecoder.Result);
|
RINOK(threadDecoder.Result);
|
||||||
|
|
||||||
@@ -1134,6 +1104,8 @@ HRESULT Update(
|
|||||||
if (folderRefIndex != folderRefs.Size())
|
if (folderRefIndex != folderRefs.Size())
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
|
RINOK(lps->SetCur());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
folderRefs.ClearAndFree();
|
folderRefs.ClearAndFree();
|
||||||
fileIndexToUpdateIndexMap.ClearAndFree();
|
fileIndexToUpdateIndexMap.ClearAndFree();
|
||||||
@@ -1169,7 +1141,7 @@ HRESULT Update(
|
|||||||
newDatabase.AddFile(file, file2);
|
newDatabase.AddFile(file, file2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newDatabase.ReserveDown();
|
newDatabase.ReserveDown();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject)
|
|||||||
|
|
||||||
STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value)
|
STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value)
|
||||||
{
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
if (formatIndex >= g_NumArcs)
|
if (formatIndex >= g_NumArcs)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
const CArcInfo &arc = *g_Arcs[formatIndex];
|
const CArcInfo &arc = *g_Arcs[formatIndex];
|
||||||
@@ -119,6 +120,7 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value
|
|||||||
}
|
}
|
||||||
prop.Detach(value);
|
prop.Detach(value);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ struct CInArchiveException
|
|||||||
{
|
{
|
||||||
kUnexpectedEndOfArchive = 0,
|
kUnexpectedEndOfArchive = 0,
|
||||||
kCRCError,
|
kCRCError,
|
||||||
kIncorrectArchive,
|
kIncorrectArchive
|
||||||
}
|
}
|
||||||
Cause;
|
Cause;
|
||||||
CInArchiveException(CCauseType cause): Cause(cause) {};
|
CInArchiveException(CCauseType cause): Cause(cause) {};
|
||||||
|
|||||||
@@ -4,13 +4,6 @@
|
|||||||
|
|
||||||
#include "Common/ComTry.h"
|
#include "Common/ComTry.h"
|
||||||
|
|
||||||
#include "Windows/PropVariant.h"
|
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
|
||||||
#include "../../Windows/System.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../Common/CreateCoder.h"
|
|
||||||
#include "../Common/ProgressUtils.h"
|
#include "../Common/ProgressUtils.h"
|
||||||
#include "../Common/RegisterArc.h"
|
#include "../Common/RegisterArc.h"
|
||||||
#include "../Common/StreamUtils.h"
|
#include "../Common/StreamUtils.h"
|
||||||
@@ -20,21 +13,13 @@
|
|||||||
#include "../Compress/CopyCoder.h"
|
#include "../Compress/CopyCoder.h"
|
||||||
|
|
||||||
#include "Common/DummyOutStream.h"
|
#include "Common/DummyOutStream.h"
|
||||||
#include "Common/ParseProperties.h"
|
#include "Common/HandlerOut.h"
|
||||||
|
|
||||||
using namespace NWindows;
|
using namespace NWindows;
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NBz2 {
|
namespace NBz2 {
|
||||||
|
|
||||||
static const UInt32 kNumPassesX1 = 1;
|
|
||||||
static const UInt32 kNumPassesX7 = 2;
|
|
||||||
static const UInt32 kNumPassesX9 = 7;
|
|
||||||
|
|
||||||
static const UInt32 kDicSizeX1 = 100000;
|
|
||||||
static const UInt32 kDicSizeX3 = 500000;
|
|
||||||
static const UInt32 kDicSizeX5 = 900000;
|
|
||||||
|
|
||||||
class CHandler:
|
class CHandler:
|
||||||
public IInArchive,
|
public IInArchive,
|
||||||
public IArchiveOpenSeq,
|
public IArchiveOpenSeq,
|
||||||
@@ -48,22 +33,7 @@ class CHandler:
|
|||||||
UInt64 _startPosition;
|
UInt64 _startPosition;
|
||||||
bool _packSizeDefined;
|
bool _packSizeDefined;
|
||||||
|
|
||||||
UInt32 _level;
|
CSingleMethodProps _props;
|
||||||
UInt32 _dicSize;
|
|
||||||
UInt32 _numPasses;
|
|
||||||
#ifndef _7ZIP_ST
|
|
||||||
UInt32 _numThreads;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void InitMethodProperties()
|
|
||||||
{
|
|
||||||
_level = 5;
|
|
||||||
_dicSize =
|
|
||||||
_numPasses = 0xFFFFFFFF;
|
|
||||||
#ifndef _7ZIP_ST
|
|
||||||
_numThreads = NWindows::NSystem::GetNumberOfProcessors();;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties)
|
MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties)
|
||||||
@@ -73,10 +43,10 @@ public:
|
|||||||
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
|
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
|
||||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
|
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
|
||||||
|
|
||||||
CHandler() { InitMethodProperties(); }
|
CHandler() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
STATPROPSTG kProps[] =
|
static const STATPROPSTG kProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidPackSize, VT_UI8}
|
{ NULL, kpidPackSize, VT_UI8}
|
||||||
};
|
};
|
||||||
@@ -87,7 +57,7 @@ IMP_IInArchive_ArcProps_NO_Table
|
|||||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||||
{
|
{
|
||||||
NCOM::CPropVariant prop;
|
NCOM::CPropVariant prop;
|
||||||
switch(propID)
|
switch (propID)
|
||||||
{
|
{
|
||||||
case kpidPhySize: if (_packSizeDefined) prop = _packSize; break;
|
case kpidPhySize: if (_packSizeDefined) prop = _packSize; break;
|
||||||
}
|
}
|
||||||
@@ -104,7 +74,7 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
|||||||
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
|
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
|
||||||
{
|
{
|
||||||
NWindows::NCOM::CPropVariant prop;
|
NWindows::NCOM::CPropVariant prop;
|
||||||
switch(propID)
|
switch (propID)
|
||||||
{
|
{
|
||||||
case kpidPackSize: if (_packSizeDefined) prop = _packSize; break;
|
case kpidPackSize: if (_packSizeDefined) prop = _packSize; break;
|
||||||
}
|
}
|
||||||
@@ -188,7 +158,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
decoderSpec->SetInStream(_seqStream);
|
decoderSpec->SetInStream(_seqStream);
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
RINOK(decoderSpec->SetNumberOfThreads(_numThreads));
|
RINOK(decoderSpec->SetNumberOfThreads(_props._numThreads));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CDummyOutStream *outStreamSpec = new CDummyOutStream;
|
CDummyOutStream *outStreamSpec = new CDummyOutStream;
|
||||||
@@ -246,50 +216,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
static HRESULT UpdateArchive(
|
static HRESULT UpdateArchive(
|
||||||
UInt64 unpackSize,
|
UInt64 unpackSize,
|
||||||
ISequentialOutStream *outStream,
|
ISequentialOutStream *outStream,
|
||||||
int indexInClient,
|
const CProps &props,
|
||||||
UInt32 dictionary,
|
|
||||||
UInt32 numPasses,
|
|
||||||
#ifndef _7ZIP_ST
|
|
||||||
UInt32 numThreads,
|
|
||||||
#endif
|
|
||||||
IArchiveUpdateCallback *updateCallback)
|
IArchiveUpdateCallback *updateCallback)
|
||||||
{
|
{
|
||||||
RINOK(updateCallback->SetTotal(unpackSize));
|
RINOK(updateCallback->SetTotal(unpackSize));
|
||||||
UInt64 complexity = 0;
|
|
||||||
RINOK(updateCallback->SetCompleted(&complexity));
|
|
||||||
|
|
||||||
CMyComPtr<ISequentialInStream> fileInStream;
|
CMyComPtr<ISequentialInStream> fileInStream;
|
||||||
|
RINOK(updateCallback->GetStream(0, &fileInStream));
|
||||||
RINOK(updateCallback->GetStream(indexInClient, &fileInStream));
|
|
||||||
|
|
||||||
CLocalProgress *localProgressSpec = new CLocalProgress;
|
CLocalProgress *localProgressSpec = new CLocalProgress;
|
||||||
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
|
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
|
||||||
localProgressSpec->Init(updateCallback, true);
|
localProgressSpec->Init(updateCallback, true);
|
||||||
|
|
||||||
NCompress::NBZip2::CEncoder *encoderSpec = new NCompress::NBZip2::CEncoder;
|
NCompress::NBZip2::CEncoder *encoderSpec = new NCompress::NBZip2::CEncoder;
|
||||||
CMyComPtr<ICompressCoder> encoder = encoderSpec;
|
CMyComPtr<ICompressCoder> encoder = encoderSpec;
|
||||||
{
|
RINOK(props.SetCoderProps(encoderSpec, NULL));
|
||||||
NWindows::NCOM::CPropVariant properties[] =
|
|
||||||
{
|
|
||||||
dictionary,
|
|
||||||
numPasses
|
|
||||||
#ifndef _7ZIP_ST
|
|
||||||
, numThreads
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
PROPID propIDs[] =
|
|
||||||
{
|
|
||||||
NCoderPropID::kDictionarySize,
|
|
||||||
NCoderPropID::kNumPasses
|
|
||||||
#ifndef _7ZIP_ST
|
|
||||||
, NCoderPropID::kNumThreads
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
RINOK(encoderSpec->SetCoderProperties(propIDs, properties, sizeof(propIDs) / sizeof(propIDs[0])));
|
|
||||||
}
|
|
||||||
|
|
||||||
RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
|
RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
|
||||||
|
|
||||||
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
|
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,25 +275,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
size = prop.uhVal.QuadPart;
|
size = prop.uhVal.QuadPart;
|
||||||
}
|
}
|
||||||
|
return UpdateArchive(size, outStream, _props, updateCallback);
|
||||||
UInt32 dicSize = _dicSize;
|
|
||||||
if (dicSize == 0xFFFFFFFF)
|
|
||||||
dicSize = (_level >= 5 ? kDicSizeX5 :
|
|
||||||
(_level >= 3 ? kDicSizeX3 :
|
|
||||||
kDicSizeX1));
|
|
||||||
|
|
||||||
UInt32 numPasses = _numPasses;
|
|
||||||
if (numPasses == 0xFFFFFFFF)
|
|
||||||
numPasses = (_level >= 9 ? kNumPassesX9 :
|
|
||||||
(_level >= 7 ? kNumPassesX7 :
|
|
||||||
kNumPassesX1));
|
|
||||||
|
|
||||||
return UpdateArchive(
|
|
||||||
size, outStream, 0, dicSize, numPasses,
|
|
||||||
#ifndef _7ZIP_ST
|
|
||||||
_numThreads,
|
|
||||||
#endif
|
|
||||||
updateCallback);
|
|
||||||
}
|
}
|
||||||
if (indexInArchive != 0)
|
if (indexInArchive != 0)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
@@ -365,47 +286,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
|
|
||||||
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
|
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
|
||||||
{
|
{
|
||||||
InitMethodProperties();
|
return _props.SetProperties(names, values, numProps);
|
||||||
#ifndef _7ZIP_ST
|
|
||||||
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
|
|
||||||
_numThreads = numProcessors;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (int i = 0; i < numProps; i++)
|
|
||||||
{
|
|
||||||
UString name = names[i];
|
|
||||||
name.MakeUpper();
|
|
||||||
if (name.IsEmpty())
|
|
||||||
return E_INVALIDARG;
|
|
||||||
const PROPVARIANT &prop = values[i];
|
|
||||||
if (name[0] == L'X')
|
|
||||||
{
|
|
||||||
UInt32 level = 9;
|
|
||||||
RINOK(ParsePropValue(name.Mid(1), prop, level));
|
|
||||||
_level = level;
|
|
||||||
}
|
|
||||||
else if (name[0] == L'D')
|
|
||||||
{
|
|
||||||
UInt32 dicSize = kDicSizeX5;
|
|
||||||
RINOK(ParsePropDictionaryValue(name.Mid(1), prop, dicSize));
|
|
||||||
_dicSize = dicSize;
|
|
||||||
}
|
|
||||||
else if (name.Left(4) == L"PASS")
|
|
||||||
{
|
|
||||||
UInt32 num = kNumPassesX9;
|
|
||||||
RINOK(ParsePropValue(name.Mid(4), prop, num));
|
|
||||||
_numPasses = num;
|
|
||||||
}
|
|
||||||
else if (name.Left(2) == L"MT")
|
|
||||||
{
|
|
||||||
#ifndef _7ZIP_ST
|
|
||||||
RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _numThreads));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static IInArchive *CreateArc() { return new CHandler; }
|
static IInArchive *CreateArc() { return new CHandler; }
|
||||||
|
|||||||
@@ -4,9 +4,7 @@
|
|||||||
|
|
||||||
#include "../../../../C/Alloc.h"
|
#include "../../../../C/Alloc.h"
|
||||||
|
|
||||||
#include "Common/Buffer.h"
|
|
||||||
#include "Common/ComTry.h"
|
#include "Common/ComTry.h"
|
||||||
#include "Common/Defs.h"
|
|
||||||
#include "Common/IntToString.h"
|
#include "Common/IntToString.h"
|
||||||
#include "Common/StringConvert.h"
|
#include "Common/StringConvert.h"
|
||||||
#include "Common/UTFConvert.h"
|
#include "Common/UTFConvert.h"
|
||||||
@@ -41,7 +39,7 @@ enum
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
STATPROPSTG kProps[] =
|
static STATPROPSTG kProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidPath, VT_BSTR},
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
{ NULL, kpidSize, VT_UI8},
|
{ NULL, kpidSize, VT_UI8},
|
||||||
@@ -57,18 +55,18 @@ STATPROPSTG kProps[] =
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static const wchar_t *kMethods[] =
|
static const char *kMethods[] =
|
||||||
{
|
{
|
||||||
L"None",
|
"None",
|
||||||
L"MSZip",
|
"MSZip",
|
||||||
L"Quantum",
|
"Quantum",
|
||||||
L"LZX"
|
"LZX"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
|
static const int kNumMethods = sizeof(kMethods) / sizeof(kMethods[0]);
|
||||||
static const wchar_t *kUnknownMethod = L"Unknown";
|
static const char *kUnknownMethod = "Unknown";
|
||||||
|
|
||||||
STATPROPSTG kArcProps[] =
|
static STATPROPSTG kArcProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidMethod, VT_BSTR},
|
{ NULL, kpidMethod, VT_BSTR},
|
||||||
// { NULL, kpidSolid, VT_BOOL},
|
// { NULL, kpidSolid, VT_BOOL},
|
||||||
@@ -87,7 +85,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
{
|
{
|
||||||
case kpidMethod:
|
case kpidMethod:
|
||||||
{
|
{
|
||||||
UString resString;
|
AString resString;
|
||||||
CRecordVector<Byte> ids;
|
CRecordVector<Byte> ids;
|
||||||
int i;
|
int i;
|
||||||
for (int v = 0; v < m_Database.Volumes.Size(); v++)
|
for (int v = 0; v < m_Database.Volumes.Size(); v++)
|
||||||
@@ -99,9 +97,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
for (i = 0; i < ids.Size(); i++)
|
for (i = 0; i < ids.Size(); i++)
|
||||||
{
|
{
|
||||||
Byte id = ids[i];
|
Byte id = ids[i];
|
||||||
UString method = (id < kNumMethods) ? kMethods[id] : kUnknownMethod;
|
AString method = (id < kNumMethods) ? kMethods[id] : kUnknownMethod;
|
||||||
if (!resString.IsEmpty())
|
if (!resString.IsEmpty())
|
||||||
resString += L' ';
|
resString += ' ';
|
||||||
resString += method;
|
resString += method;
|
||||||
}
|
}
|
||||||
prop = resString;
|
prop = resString;
|
||||||
@@ -171,12 +169,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
UInt32 realFolderIndex = item.GetFolderIndex(db.Folders.Size());
|
UInt32 realFolderIndex = item.GetFolderIndex(db.Folders.Size());
|
||||||
const CFolder &folder = db.Folders[realFolderIndex];
|
const CFolder &folder = db.Folders[realFolderIndex];
|
||||||
int methodIndex = folder.GetCompressionMethod();
|
int methodIndex = folder.GetCompressionMethod();
|
||||||
UString method = (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod;
|
AString method = (methodIndex < kNumMethods) ? kMethods[methodIndex] : kUnknownMethod;
|
||||||
if (methodIndex == NHeader::NCompressionMethodMajor::kLZX ||
|
if (methodIndex == NHeader::NCompressionMethodMajor::kLZX ||
|
||||||
methodIndex == NHeader::NCompressionMethodMajor::kQuantum)
|
methodIndex == NHeader::NCompressionMethodMajor::kQuantum)
|
||||||
{
|
{
|
||||||
method += L":";
|
method += ':';
|
||||||
wchar_t temp[32];
|
char temp[32];
|
||||||
ConvertUInt64ToString(folder.CompressionTypeMinor, temp);
|
ConvertUInt64ToString(folder.CompressionTypeMinor, temp);
|
||||||
method += temp;
|
method += temp;
|
||||||
}
|
}
|
||||||
@@ -654,7 +652,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
bool allFilesMode = (numItems == (UInt32)-1);
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems = m_Database.Items.Size();
|
numItems = m_Database.Items.Size();
|
||||||
if(numItems == 0)
|
if (numItems == 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
bool testMode = (testModeSpec != 0);
|
bool testMode = (testModeSpec != 0);
|
||||||
UInt64 totalUnPacked = 0;
|
UInt64 totalUnPacked = 0;
|
||||||
@@ -780,12 +778,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
curUnpack, extractCallback, testMode);
|
curUnpack, extractCallback, testMode);
|
||||||
|
|
||||||
cabBlockInStreamSpec->MsZip = false;
|
cabBlockInStreamSpec->MsZip = false;
|
||||||
|
HRESULT res = S_OK;
|
||||||
switch(folder.GetCompressionMethod())
|
switch(folder.GetCompressionMethod())
|
||||||
{
|
{
|
||||||
case NHeader::NCompressionMethodMajor::kNone:
|
case NHeader::NCompressionMethodMajor::kNone:
|
||||||
break;
|
break;
|
||||||
case NHeader::NCompressionMethodMajor::kMSZip:
|
case NHeader::NCompressionMethodMajor::kMSZip:
|
||||||
if(deflateDecoderSpec == NULL)
|
if (!deflateDecoder)
|
||||||
{
|
{
|
||||||
deflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder;
|
deflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder;
|
||||||
deflateDecoder = deflateDecoderSpec;
|
deflateDecoder = deflateDecoderSpec;
|
||||||
@@ -793,33 +792,35 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
cabBlockInStreamSpec->MsZip = true;
|
cabBlockInStreamSpec->MsZip = true;
|
||||||
break;
|
break;
|
||||||
case NHeader::NCompressionMethodMajor::kLZX:
|
case NHeader::NCompressionMethodMajor::kLZX:
|
||||||
if(lzxDecoderSpec == NULL)
|
if (!lzxDecoder)
|
||||||
{
|
{
|
||||||
lzxDecoderSpec = new NCompress::NLzx::CDecoder;
|
lzxDecoderSpec = new NCompress::NLzx::CDecoder;
|
||||||
lzxDecoder = lzxDecoderSpec;
|
lzxDecoder = lzxDecoderSpec;
|
||||||
}
|
}
|
||||||
RINOK(lzxDecoderSpec->SetParams(folder.CompressionTypeMinor));
|
res = lzxDecoderSpec->SetParams(folder.CompressionTypeMinor);
|
||||||
break;
|
break;
|
||||||
case NHeader::NCompressionMethodMajor::kQuantum:
|
case NHeader::NCompressionMethodMajor::kQuantum:
|
||||||
if(quantumDecoderSpec == NULL)
|
if (!quantumDecoder)
|
||||||
{
|
{
|
||||||
quantumDecoderSpec = new NCompress::NQuantum::CDecoder;
|
quantumDecoderSpec = new NCompress::NQuantum::CDecoder;
|
||||||
quantumDecoder = quantumDecoderSpec;
|
quantumDecoder = quantumDecoderSpec;
|
||||||
}
|
}
|
||||||
quantumDecoderSpec->SetParams(folder.CompressionTypeMinor);
|
res = quantumDecoderSpec->SetParams(folder.CompressionTypeMinor);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
res = E_INVALIDARG;
|
||||||
RINOK(cabFolderOutStream->Unsupported());
|
break;
|
||||||
totalUnPacked += curUnpack;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res == E_INVALIDARG)
|
||||||
|
{
|
||||||
|
RINOK(cabFolderOutStream->Unsupported());
|
||||||
|
totalUnPacked += curUnpack;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
RINOK(res);
|
||||||
|
|
||||||
cabBlockInStreamSpec->InitForNewFolder();
|
cabBlockInStreamSpec->InitForNewFolder();
|
||||||
|
|
||||||
HRESULT res = S_OK;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
int volIndex = mvItem.VolumeIndex;
|
int volIndex = mvItem.VolumeIndex;
|
||||||
int locFolderIndex = item.GetFolderIndex(db.Folders.Size());
|
int locFolderIndex = item.GetFolderIndex(db.Folders.Size());
|
||||||
|
|||||||
@@ -9,18 +9,15 @@
|
|||||||
|
|
||||||
#include "ChmIn.h"
|
#include "ChmIn.h"
|
||||||
|
|
||||||
namespace NArchive{
|
namespace NArchive {
|
||||||
namespace NChm{
|
namespace NChm {
|
||||||
|
|
||||||
// define CHM_LOW, if you want to see low level items
|
// define CHM_LOW, if you want to see low level items
|
||||||
// #define CHM_LOW
|
// #define CHM_LOW
|
||||||
|
|
||||||
static const GUID kChmLzxGuid =
|
static const GUID kChmLzxGuid = { 0x7FC28940, 0x9D31, 0x11D0, { 0x9B, 0x27, 0x00, 0xA0, 0xC9, 0x1E, 0x9C, 0x7C } };
|
||||||
{ 0x7FC28940, 0x9D31, 0x11D0, 0x9B, 0x27, 0x00, 0xA0, 0xC9, 0x1E, 0x9C, 0x7C };
|
static const GUID kHelp2LzxGuid = { 0x0A9007C6, 0x4076, 0x11D3, { 0x87, 0x89, 0x00, 0x00, 0xF8, 0x10, 0x57, 0x54 } };
|
||||||
static const GUID kHelp2LzxGuid =
|
static const GUID kDesGuid = { 0x67F6E4A2, 0x60BF, 0x11D3, { 0x85, 0x40, 0x00, 0xC0, 0x4F, 0x58, 0xC3, 0xCF } };
|
||||||
{ 0x0A9007C6, 0x4076, 0x11D3, 0x87, 0x89, 0x00, 0x00, 0xF8, 0x10, 0x57, 0x54 };
|
|
||||||
static const GUID kDesGuid =
|
|
||||||
{ 0x67F6E4A2, 0x60BF, 0x11D3, 0x85, 0x40, 0x00, 0xC0, 0x4F, 0x58, 0xC3, 0xCF };
|
|
||||||
|
|
||||||
static bool AreGuidsEqual(REFGUID g1, REFGUID g2)
|
static bool AreGuidsEqual(REFGUID g1, REFGUID g2)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ struct CItem
|
|||||||
{
|
{
|
||||||
if (Name.Length() == 0)
|
if (Name.Length() == 0)
|
||||||
return false;
|
return false;
|
||||||
return (Name[Name.Length() - 1] == '/');
|
return (Name.Back() == '/');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams):
|
|||||||
{
|
{
|
||||||
InSizes.Reserve(NumInStreams);
|
InSizes.Reserve(NumInStreams);
|
||||||
InSizePointers.Reserve(NumInStreams);
|
InSizePointers.Reserve(NumInStreams);
|
||||||
OutSizePointers.Reserve(NumOutStreams);
|
OutSizes.Reserve(NumOutStreams);
|
||||||
OutSizePointers.Reserve(NumOutStreams);
|
OutSizePointers.Reserve(NumOutStreams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
|
|||||||
|
|
||||||
for (i = 0; i < _coders.Size(); i++)
|
for (i = 0; i < _coders.Size(); i++)
|
||||||
if (i != _progressCoderIndex)
|
if (i != _progressCoderIndex)
|
||||||
_coders[i].WaitFinish();
|
_coders[i].WaitExecuteFinish();
|
||||||
|
|
||||||
RINOK(ReturnIfError(E_ABORT));
|
RINOK(ReturnIfError(E_ABORT));
|
||||||
RINOK(ReturnIfError(E_OUTOFMEMORY));
|
RINOK(ReturnIfError(E_OUTOFMEMORY));
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ struct CCoder2: public CCoderInfo2, public CVirtThread
|
|||||||
CRecordVector<ISequentialOutStream*> OutStreamPointers;
|
CRecordVector<ISequentialOutStream*> OutStreamPointers;
|
||||||
|
|
||||||
CCoder2(UInt32 numInStreams, UInt32 numOutStreams);
|
CCoder2(UInt32 numInStreams, UInt32 numOutStreams);
|
||||||
|
~CCoder2() { CVirtThread::WaitThreadFinish(); }
|
||||||
void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
|
void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
|
||||||
virtual void Execute();
|
virtual void Execute();
|
||||||
void Code(ICompressProgressInfo *progress);
|
void Code(ICompressProgressInfo *progress);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include "CoderMixer2ST.h"
|
#include "CoderMixer2ST.h"
|
||||||
|
|
||||||
namespace NCoderMixer2 {
|
namespace NCoderMixer {
|
||||||
|
|
||||||
CCoderMixer2ST::CCoderMixer2ST() {}
|
CCoderMixer2ST::CCoderMixer2ST() {}
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ HRESULT CCoderMixer2ST::GetInStream(
|
|||||||
{
|
{
|
||||||
CMyComPtr<ISequentialInStream> seqInStream;
|
CMyComPtr<ISequentialInStream> seqInStream;
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < _bindInfo.InStreams.Size(); i++)
|
for (i = 0; i < _bindInfo.InStreams.Size(); i++)
|
||||||
if (_bindInfo.InStreams[i] == streamIndex)
|
if (_bindInfo.InStreams[i] == streamIndex)
|
||||||
{
|
{
|
||||||
seqInStream = inStreams[i];
|
seqInStream = inStreams[i];
|
||||||
@@ -57,7 +57,7 @@ HRESULT CCoderMixer2ST::GetInStream(
|
|||||||
_bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex,
|
_bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex,
|
||||||
coderIndex, coderStreamIndex);
|
coderIndex, coderStreamIndex);
|
||||||
|
|
||||||
CCoderInfo &coder = _coders[coderIndex];
|
CCoderInfo2 &coder = _coders[coderIndex];
|
||||||
if (!coder.Coder)
|
if (!coder.Coder)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
coder.Coder.QueryInterface(IID_ISequentialInStream, &seqInStream);
|
coder.Coder.QueryInterface(IID_ISequentialInStream, &seqInStream);
|
||||||
@@ -91,7 +91,7 @@ HRESULT CCoderMixer2ST::GetOutStream(
|
|||||||
{
|
{
|
||||||
CMyComPtr<ISequentialOutStream> seqOutStream;
|
CMyComPtr<ISequentialOutStream> seqOutStream;
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
|
for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
|
||||||
if (_bindInfo.OutStreams[i] == streamIndex)
|
if (_bindInfo.OutStreams[i] == streamIndex)
|
||||||
{
|
{
|
||||||
seqOutStream = outStreams[i];
|
seqOutStream = outStreams[i];
|
||||||
@@ -106,7 +106,7 @@ HRESULT CCoderMixer2ST::GetOutStream(
|
|||||||
_bindInfo.FindInStream(_bindInfo.BindPairs[binderIndex].InIndex,
|
_bindInfo.FindInStream(_bindInfo.BindPairs[binderIndex].InIndex,
|
||||||
coderIndex, coderStreamIndex);
|
coderIndex, coderStreamIndex);
|
||||||
|
|
||||||
CCoderInfo &coder = _coders[coderIndex];
|
CCoderInfo2 &coder = _coders[coderIndex];
|
||||||
if (!coder.Coder)
|
if (!coder.Coder)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
coder.Coder.QueryInterface(IID_ISequentialOutStream, &seqOutStream);
|
coder.Coder.QueryInterface(IID_ISequentialOutStream, &seqOutStream);
|
||||||
@@ -169,7 +169,7 @@ STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams,
|
|||||||
|
|
||||||
// _mainCoderIndex = 0;
|
// _mainCoderIndex = 0;
|
||||||
// _mainCoderIndex = _coders.Size() - 1;
|
// _mainCoderIndex = _coders.Size() - 1;
|
||||||
CCoderInfo &mainCoder = _coders[_mainCoderIndex];
|
CCoderInfo2 &mainCoder = _coders[_mainCoderIndex];
|
||||||
|
|
||||||
CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams;
|
CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams;
|
||||||
CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams;
|
CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams;
|
||||||
@@ -198,7 +198,7 @@ STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams,
|
|||||||
{
|
{
|
||||||
if (i == _mainCoderIndex)
|
if (i == _mainCoderIndex)
|
||||||
continue;
|
continue;
|
||||||
CCoderInfo &coder = _coders[i];
|
CCoderInfo2 &coder = _coders[i];
|
||||||
CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
|
CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
|
||||||
coder.Coder.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize);
|
coder.Coder.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize);
|
||||||
if (setOutStreamSize)
|
if (setOutStreamSize)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "../../../Common/MyCom.h"
|
#include "../../../Common/MyCom.h"
|
||||||
#include "../../ICoder.h"
|
#include "../../ICoder.h"
|
||||||
|
|
||||||
namespace NCoderMixer2 {
|
namespace NCoderMixer {
|
||||||
|
|
||||||
// SetBindInfo()
|
// SetBindInfo()
|
||||||
// for each coder
|
// for each coder
|
||||||
@@ -26,11 +26,11 @@ namespace NCoderMixer2 {
|
|||||||
// Code
|
// Code
|
||||||
// }
|
// }
|
||||||
|
|
||||||
struct CSTCoderInfo: public CCoderInfo
|
struct CSTCoderInfo: public CCoderInfo2
|
||||||
{
|
{
|
||||||
bool IsMain;
|
bool IsMain;
|
||||||
CSTCoderInfo(UInt32 numInStreams, UInt32 numOutStreams, bool isMain):
|
CSTCoderInfo(UInt32 numInStreams, UInt32 numOutStreams, bool isMain):
|
||||||
CCoderInfo(numInStreams, numOutStreams),IsMain(isMain) {}
|
CCoderInfo2(numInStreams, numOutStreams), IsMain(isMain) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CCoderMixer2ST:
|
class CCoderMixer2ST:
|
||||||
@@ -84,5 +84,5 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream,
|
|||||||
|
|
||||||
for (i = 0; i < _coders.Size(); i++)
|
for (i = 0; i < _coders.Size(); i++)
|
||||||
if (i != _progressCoderIndex)
|
if (i != _progressCoderIndex)
|
||||||
_coders[i].WaitFinish();
|
_coders[i].WaitExecuteFinish();
|
||||||
|
|
||||||
RINOK(ReturnIfError(E_ABORT));
|
RINOK(ReturnIfError(E_ABORT));
|
||||||
RINOK(ReturnIfError(E_OUTOFMEMORY));
|
RINOK(ReturnIfError(E_OUTOFMEMORY));
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ struct CCoder: public CCoderInfo, public CVirtThread
|
|||||||
|
|
||||||
virtual void Execute();
|
virtual void Execute();
|
||||||
void Code(ICompressProgressInfo *progress);
|
void Code(ICompressProgressInfo *progress);
|
||||||
|
~CCoder() { CVirtThread::WaitThreadFinish(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -2,16 +2,10 @@
|
|||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "../../../Common/StringToInt.h"
|
|
||||||
|
|
||||||
#include "../../../Windows/PropVariant.h"
|
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
#include "../../../Windows/System.h"
|
#include "../../../Windows/System.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
|
|
||||||
#include "../Common/ParseProperties.h"
|
#include "../Common/ParseProperties.h"
|
||||||
|
|
||||||
#include "HandlerOut.h"
|
#include "HandlerOut.h"
|
||||||
@@ -20,487 +14,40 @@ using namespace NWindows;
|
|||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
|
|
||||||
static const wchar_t *kCopyMethod = L"Copy";
|
static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value)
|
||||||
static const wchar_t *kLZMAMethodName = L"LZMA";
|
|
||||||
static const wchar_t *kLZMA2MethodName = L"LZMA2";
|
|
||||||
static const wchar_t *kBZip2MethodName = L"BZip2";
|
|
||||||
static const wchar_t *kPpmdMethodName = L"PPMd";
|
|
||||||
static const wchar_t *kDeflateMethodName = L"Deflate";
|
|
||||||
static const wchar_t *kDeflate64MethodName = L"Deflate64";
|
|
||||||
|
|
||||||
static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
|
|
||||||
static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
|
|
||||||
|
|
||||||
static const UInt32 kLzmaAlgoX1 = 0;
|
|
||||||
static const UInt32 kLzmaAlgoX5 = 1;
|
|
||||||
|
|
||||||
static const UInt32 kLzmaDicSizeX1 = 1 << 16;
|
|
||||||
static const UInt32 kLzmaDicSizeX3 = 1 << 20;
|
|
||||||
static const UInt32 kLzmaDicSizeX5 = 1 << 24;
|
|
||||||
static const UInt32 kLzmaDicSizeX7 = 1 << 25;
|
|
||||||
static const UInt32 kLzmaDicSizeX9 = 1 << 26;
|
|
||||||
|
|
||||||
static const UInt32 kLzmaFastBytesX1 = 32;
|
|
||||||
static const UInt32 kLzmaFastBytesX7 = 64;
|
|
||||||
|
|
||||||
static const UInt32 kPpmdMemSizeX1 = (1 << 22);
|
|
||||||
static const UInt32 kPpmdMemSizeX5 = (1 << 24);
|
|
||||||
static const UInt32 kPpmdMemSizeX7 = (1 << 26);
|
|
||||||
static const UInt32 kPpmdMemSizeX9 = (192 << 20);
|
|
||||||
|
|
||||||
static const UInt32 kPpmdOrderX1 = 4;
|
|
||||||
static const UInt32 kPpmdOrderX5 = 6;
|
|
||||||
static const UInt32 kPpmdOrderX7 = 16;
|
|
||||||
static const UInt32 kPpmdOrderX9 = 32;
|
|
||||||
|
|
||||||
static const UInt32 kDeflateAlgoX1 = 0;
|
|
||||||
static const UInt32 kDeflateAlgoX5 = 1;
|
|
||||||
|
|
||||||
static const UInt32 kDeflateFastBytesX1 = 32;
|
|
||||||
static const UInt32 kDeflateFastBytesX7 = 64;
|
|
||||||
static const UInt32 kDeflateFastBytesX9 = 128;
|
|
||||||
|
|
||||||
static const UInt32 kDeflatePassesX1 = 1;
|
|
||||||
static const UInt32 kDeflatePassesX7 = 3;
|
|
||||||
static const UInt32 kDeflatePassesX9 = 10;
|
|
||||||
|
|
||||||
static const UInt32 kBZip2NumPassesX1 = 1;
|
|
||||||
static const UInt32 kBZip2NumPassesX7 = 2;
|
|
||||||
static const UInt32 kBZip2NumPassesX9 = 7;
|
|
||||||
|
|
||||||
static const UInt32 kBZip2DicSizeX1 = 100000;
|
|
||||||
static const UInt32 kBZip2DicSizeX3 = 500000;
|
|
||||||
static const UInt32 kBZip2DicSizeX5 = 900000;
|
|
||||||
|
|
||||||
static const wchar_t *kDefaultMethodName = kLZMAMethodName;
|
|
||||||
|
|
||||||
static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
|
|
||||||
static const UInt32 kDictionaryForHeaders = 1 << 20;
|
|
||||||
static const UInt32 kNumFastBytesForHeaders = 273;
|
|
||||||
static const UInt32 kAlgorithmForHeaders = kLzmaAlgoX5;
|
|
||||||
|
|
||||||
static bool AreEqual(const UString &methodName, const wchar_t *s)
|
|
||||||
{ return (methodName.CompareNoCase(s) == 0); }
|
|
||||||
|
|
||||||
bool COneMethodInfo::IsLzma() const
|
|
||||||
{
|
{
|
||||||
return
|
if (m.FindProp(propID) < 0)
|
||||||
AreEqual(MethodName, kLZMAMethodName) ||
|
m.AddProp32(propID, value);
|
||||||
AreEqual(MethodName, kLZMA2MethodName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool IsBZip2Method(const UString &methodName)
|
void CMultiMethodProps::SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo
|
||||||
{ return AreEqual(methodName, kBZip2MethodName); }
|
|
||||||
|
|
||||||
static inline bool IsPpmdMethod(const UString &methodName)
|
|
||||||
{ return AreEqual(methodName, kPpmdMethodName); }
|
|
||||||
|
|
||||||
static inline bool IsDeflateMethod(const UString &methodName)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
AreEqual(methodName, kDeflateMethodName) ||
|
|
||||||
AreEqual(methodName, kDeflate64MethodName);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CNameToPropID
|
|
||||||
{
|
|
||||||
PROPID PropID;
|
|
||||||
VARTYPE VarType;
|
|
||||||
const wchar_t *Name;
|
|
||||||
};
|
|
||||||
|
|
||||||
static CNameToPropID g_NameToPropID[] =
|
|
||||||
{
|
|
||||||
{ NCoderPropID::kBlockSize, VT_UI4, L"C" },
|
|
||||||
{ NCoderPropID::kDictionarySize, VT_UI4, L"D" },
|
|
||||||
{ NCoderPropID::kUsedMemorySize, VT_UI4, L"MEM" },
|
|
||||||
|
|
||||||
{ NCoderPropID::kOrder, VT_UI4, L"O" },
|
|
||||||
{ NCoderPropID::kPosStateBits, VT_UI4, L"PB" },
|
|
||||||
{ NCoderPropID::kLitContextBits, VT_UI4, L"LC" },
|
|
||||||
{ NCoderPropID::kLitPosBits, VT_UI4, L"LP" },
|
|
||||||
{ NCoderPropID::kEndMarker, VT_BOOL, L"eos" },
|
|
||||||
|
|
||||||
{ NCoderPropID::kNumPasses, VT_UI4, L"Pass" },
|
|
||||||
{ NCoderPropID::kNumFastBytes, VT_UI4, L"fb" },
|
|
||||||
{ NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" },
|
|
||||||
{ NCoderPropID::kAlgorithm, VT_UI4, L"a" },
|
|
||||||
{ NCoderPropID::kMatchFinder, VT_BSTR, L"mf" },
|
|
||||||
{ NCoderPropID::kNumThreads, VT_UI4, L"mt" },
|
|
||||||
{ NCoderPropID::kDefaultProp, VT_UI4, L"" }
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType, NCOM::CPropVariant &destProp)
|
|
||||||
{
|
|
||||||
if (varType == srcProp.vt)
|
|
||||||
{
|
|
||||||
destProp = srcProp;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (varType == VT_UI1)
|
|
||||||
{
|
|
||||||
if (srcProp.vt == VT_UI4)
|
|
||||||
{
|
|
||||||
UInt32 value = srcProp.ulVal;
|
|
||||||
if (value > 0xFF)
|
|
||||||
return false;
|
|
||||||
destProp = (Byte)value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (varType == VT_BOOL)
|
|
||||||
{
|
|
||||||
bool res;
|
|
||||||
if (SetBoolProperty(res, srcProp) != S_OK)
|
|
||||||
return false;
|
|
||||||
destProp = res;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int FindPropIdExact(const UString &name)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)
|
|
||||||
if (name.CompareNoCase(g_NameToPropID[i].Name) == 0)
|
|
||||||
return i;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int FindPropIdStart(const UString &name)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)
|
|
||||||
{
|
|
||||||
UString t = g_NameToPropID[i].Name;
|
|
||||||
if (t.CompareNoCase(name.Left(t.Length())) == 0)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SetMethodProp(COneMethodInfo &m, PROPID propID, const NCOM::CPropVariant &value)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < m.Props.Size(); j++)
|
|
||||||
if (m.Props[j].Id == propID)
|
|
||||||
return;
|
|
||||||
CProp prop;
|
|
||||||
prop.Id = propID;
|
|
||||||
prop.Value = value;
|
|
||||||
m.Props.Add(prop);
|
|
||||||
}
|
|
||||||
|
|
||||||
void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
, UInt32 numThreads
|
, UInt32 numThreads
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UInt32 level = _level;
|
UInt32 level = _level;
|
||||||
if (oneMethodInfo.MethodName.IsEmpty())
|
if (level != (UInt32)(UInt32)-1)
|
||||||
oneMethodInfo.MethodName = kDefaultMethodName;
|
SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
|
||||||
|
|
||||||
if (oneMethodInfo.IsLzma())
|
|
||||||
{
|
|
||||||
UInt32 dicSize =
|
|
||||||
(level >= 9 ? kLzmaDicSizeX9 :
|
|
||||||
(level >= 7 ? kLzmaDicSizeX7 :
|
|
||||||
(level >= 5 ? kLzmaDicSizeX5 :
|
|
||||||
(level >= 3 ? kLzmaDicSizeX3 :
|
|
||||||
kLzmaDicSizeX1))));
|
|
||||||
|
|
||||||
UInt32 algo =
|
|
||||||
(level >= 5 ? kLzmaAlgoX5 :
|
|
||||||
kLzmaAlgoX1);
|
|
||||||
|
|
||||||
UInt32 fastBytes =
|
|
||||||
(level >= 7 ? kLzmaFastBytesX7 :
|
|
||||||
kLzmaFastBytesX1);
|
|
||||||
|
|
||||||
const wchar_t *matchFinder =
|
|
||||||
(level >= 5 ? kLzmaMatchFinderX5 :
|
|
||||||
kLzmaMatchFinderX1);
|
|
||||||
|
|
||||||
SetMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
|
|
||||||
SetMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
|
|
||||||
SetMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
|
|
||||||
SetMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder);
|
|
||||||
#ifndef _7ZIP_ST
|
|
||||||
SetMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (IsDeflateMethod(oneMethodInfo.MethodName))
|
|
||||||
{
|
|
||||||
UInt32 fastBytes =
|
|
||||||
(level >= 9 ? kDeflateFastBytesX9 :
|
|
||||||
(level >= 7 ? kDeflateFastBytesX7 :
|
|
||||||
kDeflateFastBytesX1));
|
|
||||||
|
|
||||||
UInt32 numPasses =
|
|
||||||
(level >= 9 ? kDeflatePassesX9 :
|
|
||||||
(level >= 7 ? kDeflatePassesX7 :
|
|
||||||
kDeflatePassesX1));
|
|
||||||
|
|
||||||
UInt32 algo =
|
|
||||||
(level >= 5 ? kDeflateAlgoX5 :
|
|
||||||
kDeflateAlgoX1);
|
|
||||||
|
|
||||||
SetMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
|
|
||||||
SetMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
|
|
||||||
SetMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
|
|
||||||
}
|
|
||||||
else if (IsBZip2Method(oneMethodInfo.MethodName))
|
|
||||||
{
|
|
||||||
UInt32 numPasses =
|
|
||||||
(level >= 9 ? kBZip2NumPassesX9 :
|
|
||||||
(level >= 7 ? kBZip2NumPassesX7 :
|
|
||||||
kBZip2NumPassesX1));
|
|
||||||
|
|
||||||
UInt32 dicSize =
|
|
||||||
(level >= 5 ? kBZip2DicSizeX5 :
|
|
||||||
(level >= 3 ? kBZip2DicSizeX3 :
|
|
||||||
kBZip2DicSizeX1));
|
|
||||||
|
|
||||||
SetMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
|
|
||||||
SetMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
|
|
||||||
#ifndef _7ZIP_ST
|
|
||||||
SetMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (IsPpmdMethod(oneMethodInfo.MethodName))
|
|
||||||
{
|
|
||||||
UInt32 useMemSize =
|
|
||||||
(level >= 9 ? kPpmdMemSizeX9 :
|
|
||||||
(level >= 7 ? kPpmdMemSizeX7 :
|
|
||||||
(level >= 5 ? kPpmdMemSizeX5 :
|
|
||||||
kPpmdMemSizeX1)));
|
|
||||||
|
|
||||||
UInt32 order =
|
|
||||||
(level >= 9 ? kPpmdOrderX9 :
|
|
||||||
(level >= 7 ? kPpmdOrderX7 :
|
|
||||||
(level >= 5 ? kPpmdOrderX5 :
|
|
||||||
kPpmdOrderX1)));
|
|
||||||
|
|
||||||
SetMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize);
|
|
||||||
SetMethodProp(oneMethodInfo, NCoderPropID::kOrder, order);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SplitParams(const UString &srcString, UStringVector &subStrings)
|
|
||||||
{
|
|
||||||
subStrings.Clear();
|
|
||||||
UString name;
|
|
||||||
int len = srcString.Length();
|
|
||||||
if (len == 0)
|
|
||||||
return;
|
|
||||||
for (int i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
wchar_t c = srcString[i];
|
|
||||||
if (c == L':')
|
|
||||||
{
|
|
||||||
subStrings.Add(name);
|
|
||||||
name.Empty();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
name += c;
|
|
||||||
}
|
|
||||||
subStrings.Add(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SplitParam(const UString ¶m, UString &name, UString &value)
|
|
||||||
{
|
|
||||||
int eqPos = param.Find(L'=');
|
|
||||||
if (eqPos >= 0)
|
|
||||||
{
|
|
||||||
name = param.Left(eqPos);
|
|
||||||
value = param.Mid(eqPos + 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for(int i = 0; i < param.Length(); i++)
|
|
||||||
{
|
|
||||||
wchar_t c = param[i];
|
|
||||||
if (c >= L'0' && c <= L'9')
|
|
||||||
{
|
|
||||||
name = param.Left(i);
|
|
||||||
value = param.Mid(i);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
name = param;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT COutHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value)
|
|
||||||
{
|
|
||||||
CProp prop;
|
|
||||||
int index = FindPropIdExact(name);
|
|
||||||
if (index < 0)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
const CNameToPropID &nameToPropID = g_NameToPropID[index];
|
|
||||||
prop.Id = nameToPropID.PropID;
|
|
||||||
|
|
||||||
if (prop.Id == NCoderPropID::kBlockSize ||
|
|
||||||
prop.Id == NCoderPropID::kDictionarySize ||
|
|
||||||
prop.Id == NCoderPropID::kUsedMemorySize)
|
|
||||||
{
|
|
||||||
UInt32 dicSize;
|
|
||||||
RINOK(ParsePropDictionaryValue(value, dicSize));
|
|
||||||
prop.Value = dicSize;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NCOM::CPropVariant propValue;
|
|
||||||
|
|
||||||
if (nameToPropID.VarType == VT_BSTR)
|
|
||||||
propValue = value;
|
|
||||||
else if (nameToPropID.VarType == VT_BOOL)
|
|
||||||
{
|
|
||||||
bool res;
|
|
||||||
if (!StringToBool(value, res))
|
|
||||||
return E_INVALIDARG;
|
|
||||||
propValue = res;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UInt32 number;
|
|
||||||
if (ParseStringToUInt32(value, number) == value.Length())
|
|
||||||
propValue = number;
|
|
||||||
else
|
|
||||||
propValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ConvertProperty(propValue, nameToPropID.VarType, prop.Value))
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
oneMethodInfo.Props.Add(prop);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT COutHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString)
|
|
||||||
{
|
|
||||||
UStringVector params;
|
|
||||||
SplitParams(srcString, params);
|
|
||||||
if (params.Size() > 0)
|
|
||||||
oneMethodInfo.MethodName = params[0];
|
|
||||||
for (int i = 1; i < params.Size(); i++)
|
|
||||||
{
|
|
||||||
const UString ¶m = params[i];
|
|
||||||
UString name, value;
|
|
||||||
SplitParam(param, name, value);
|
|
||||||
RINOK(SetParam(oneMethodInfo, name, value));
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT COutHandler::SetSolidSettings(const UString &s)
|
|
||||||
{
|
|
||||||
UString s2 = s;
|
|
||||||
s2.MakeUpper();
|
|
||||||
for (int i = 0; i < s2.Length();)
|
|
||||||
{
|
|
||||||
const wchar_t *start = ((const wchar_t *)s2) + i;
|
|
||||||
const wchar_t *end;
|
|
||||||
UInt64 v = ConvertStringToUInt64(start, &end);
|
|
||||||
if (start == end)
|
|
||||||
{
|
|
||||||
if (s2[i++] != 'E')
|
|
||||||
return E_INVALIDARG;
|
|
||||||
_solidExtension = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
i += (int)(end - start);
|
|
||||||
if (i == s2.Length())
|
|
||||||
return E_INVALIDARG;
|
|
||||||
wchar_t c = s2[i++];
|
|
||||||
switch(c)
|
|
||||||
{
|
|
||||||
case 'F':
|
|
||||||
if (v < 1)
|
|
||||||
v = 1;
|
|
||||||
_numSolidFiles = v;
|
|
||||||
break;
|
|
||||||
case 'B':
|
|
||||||
_numSolidBytes = v;
|
|
||||||
_numSolidBytesDefined = true;
|
|
||||||
break;
|
|
||||||
case 'K':
|
|
||||||
_numSolidBytes = (v << 10);
|
|
||||||
_numSolidBytesDefined = true;
|
|
||||||
break;
|
|
||||||
case 'M':
|
|
||||||
_numSolidBytes = (v << 20);
|
|
||||||
_numSolidBytesDefined = true;
|
|
||||||
break;
|
|
||||||
case 'G':
|
|
||||||
_numSolidBytes = (v << 30);
|
|
||||||
_numSolidBytesDefined = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT COutHandler::SetSolidSettings(const PROPVARIANT &value)
|
|
||||||
{
|
|
||||||
bool isSolid;
|
|
||||||
switch(value.vt)
|
|
||||||
{
|
|
||||||
case VT_EMPTY:
|
|
||||||
isSolid = true;
|
|
||||||
break;
|
|
||||||
case VT_BOOL:
|
|
||||||
isSolid = (value.boolVal != VARIANT_FALSE);
|
|
||||||
break;
|
|
||||||
case VT_BSTR:
|
|
||||||
if (StringToBool(value.bstrVal, isSolid))
|
|
||||||
break;
|
|
||||||
return SetSolidSettings(value.bstrVal);
|
|
||||||
default:
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
if (isSolid)
|
|
||||||
InitSolid();
|
|
||||||
else
|
|
||||||
_numSolidFiles = 1;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void COutHandler::Init()
|
|
||||||
{
|
|
||||||
_removeSfxBlock = false;
|
|
||||||
_compressHeaders = true;
|
|
||||||
_encryptHeadersSpecified = false;
|
|
||||||
_encryptHeaders = false;
|
|
||||||
|
|
||||||
WriteCTime = false;
|
|
||||||
WriteATime = false;
|
|
||||||
WriteMTime = true;
|
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
_numThreads = NSystem::GetNumberOfProcessors();
|
SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMultiMethodProps::Init()
|
||||||
|
{
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
_numProcessors = _numThreads = NSystem::GetNumberOfProcessors();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_level = 5;
|
_level = (UInt32)(UInt32)-1;
|
||||||
_autoFilter = true;
|
_autoFilter = true;
|
||||||
_volumeMode = false;
|
|
||||||
_crcSize = 4;
|
_crcSize = 4;
|
||||||
InitSolid();
|
_filterMethod.Clear();
|
||||||
|
_methods.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void COutHandler::BeforeSetProperty()
|
HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
|
||||||
{
|
|
||||||
Init();
|
|
||||||
#ifndef _7ZIP_ST
|
|
||||||
numProcessors = NSystem::GetNumberOfProcessors();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mainDicSize = 0xFFFFFFFF;
|
|
||||||
mainDicMethodIndex = 0xFFFFFFFF;
|
|
||||||
minNumber = 0;
|
|
||||||
_crcSize = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
|
|
||||||
{
|
{
|
||||||
UString name = nameSpec;
|
UString name = nameSpec;
|
||||||
name.MakeUpper();
|
name.MakeUpper();
|
||||||
@@ -511,24 +58,14 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
|
|||||||
{
|
{
|
||||||
name.Delete(0);
|
name.Delete(0);
|
||||||
_level = 9;
|
_level = 9;
|
||||||
return ParsePropValue(name, value, _level);
|
return ParsePropToUInt32(name, value, _level);
|
||||||
}
|
|
||||||
|
|
||||||
if (name[0] == L'S')
|
|
||||||
{
|
|
||||||
name.Delete(0);
|
|
||||||
if (name.IsEmpty())
|
|
||||||
return SetSolidSettings(value);
|
|
||||||
if (value.vt != VT_EMPTY)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
return SetSolidSettings(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name == L"CRC")
|
if (name == L"CRC")
|
||||||
{
|
{
|
||||||
_crcSize = 4;
|
|
||||||
name.Delete(0, 3);
|
name.Delete(0, 3);
|
||||||
return ParsePropValue(name, value, _crcSize);
|
_crcSize = 4;
|
||||||
|
return ParsePropToUInt32(name, value, _crcSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 number;
|
UInt32 number;
|
||||||
@@ -536,86 +73,67 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
|
|||||||
UString realName = name.Mid(index);
|
UString realName = name.Mid(index);
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
{
|
{
|
||||||
if(name.Left(2).CompareNoCase(L"MT") == 0)
|
if (name.Left(2).CompareNoCase(L"MT") == 0)
|
||||||
{
|
{
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
|
RINOK(ParseMtProp(name.Mid(2), value, _numProcessors, _numThreads));
|
||||||
#endif
|
#endif
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
if (name.CompareNoCase(L"RSFX") == 0) return SetBoolProperty(_removeSfxBlock, value);
|
if (name.CompareNoCase(L"F") == 0)
|
||||||
if (name.CompareNoCase(L"F") == 0) return SetBoolProperty(_autoFilter, value);
|
|
||||||
if (name.CompareNoCase(L"HC") == 0) return SetBoolProperty(_compressHeaders, value);
|
|
||||||
if (name.CompareNoCase(L"HCF") == 0)
|
|
||||||
{
|
{
|
||||||
bool compressHeadersFull = true;
|
HRESULT res = PROPVARIANT_to_bool(value, _autoFilter);
|
||||||
RINOK(SetBoolProperty(compressHeadersFull, value));
|
if (res == S_OK)
|
||||||
if (!compressHeadersFull)
|
return res;
|
||||||
|
if (value.vt != VT_BSTR)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
return S_OK;
|
return _filterMethod.ParseMethodFromPROPVARIANT(L"", value);
|
||||||
}
|
}
|
||||||
if (name.CompareNoCase(L"HE") == 0)
|
|
||||||
{
|
|
||||||
RINOK(SetBoolProperty(_encryptHeaders, value));
|
|
||||||
_encryptHeadersSpecified = true;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
if (name.CompareNoCase(L"TC") == 0) return SetBoolProperty(WriteCTime, value);
|
|
||||||
if (name.CompareNoCase(L"TA") == 0) return SetBoolProperty(WriteATime, value);
|
|
||||||
if (name.CompareNoCase(L"TM") == 0) return SetBoolProperty(WriteMTime, value);
|
|
||||||
if (name.CompareNoCase(L"V") == 0) return SetBoolProperty(_volumeMode, value);
|
|
||||||
number = 0;
|
number = 0;
|
||||||
}
|
}
|
||||||
if (number > 10000)
|
if (number > 64)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
if (number < minNumber)
|
for (int j = _methods.Size(); j <= (int)number; j++)
|
||||||
return E_INVALIDARG;
|
_methods.Add(COneMethodInfo());
|
||||||
number -= minNumber;
|
return _methods[number].ParseMethodFromPROPVARIANT(realName, value);
|
||||||
for(int j = _methods.Size(); j <= (int)number; j++)
|
}
|
||||||
{
|
|
||||||
COneMethodInfo oneMethodInfo;
|
|
||||||
_methods.Add(oneMethodInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
COneMethodInfo &oneMethodInfo = _methods[number];
|
|
||||||
|
|
||||||
if (realName.Length() == 0)
|
|
||||||
{
|
|
||||||
if (value.vt != VT_BSTR)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
RINOK(SetParams(oneMethodInfo, value.bstrVal));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int index = FindPropIdStart(realName);
|
|
||||||
if (index < 0)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
const CNameToPropID &nameToPropID = g_NameToPropID[index];
|
|
||||||
CProp prop;
|
|
||||||
prop.Id = nameToPropID.PropID;
|
|
||||||
|
|
||||||
if (prop.Id == NCoderPropID::kBlockSize ||
|
void CSingleMethodProps::Init()
|
||||||
prop.Id == NCoderPropID::kDictionarySize ||
|
{
|
||||||
prop.Id == NCoderPropID::kUsedMemorySize)
|
Clear();
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
_numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
|
||||||
|
AddNumThreadsProp(_numThreads);
|
||||||
|
#endif
|
||||||
|
_level = (UInt32)(UInt32)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CSingleMethodProps::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
for (int i = 0; i < numProps; i++)
|
||||||
|
{
|
||||||
|
UString name = names[i];
|
||||||
|
name.MakeUpper();
|
||||||
|
if (name.IsEmpty())
|
||||||
|
return E_INVALIDARG;
|
||||||
|
const PROPVARIANT &value = values[i];
|
||||||
|
if (name[0] == L'X')
|
||||||
{
|
{
|
||||||
UInt32 dicSize;
|
UInt32 a = 9;
|
||||||
RINOK(ParsePropDictionaryValue(realName.Mid(MyStringLen(nameToPropID.Name)), value, dicSize));
|
RINOK(ParsePropToUInt32(name.Mid(1), value, a));
|
||||||
prop.Value = dicSize;
|
_level = a;
|
||||||
if (number <= mainDicMethodIndex)
|
AddLevelProp(a);
|
||||||
mainDicSize = dicSize;
|
}
|
||||||
|
else if (name.Left(2).CompareNoCase(L"MT") == 0)
|
||||||
|
{
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
RINOK(ParseMtProp(name.Mid(2), value, _numProcessors, _numThreads));
|
||||||
|
AddNumThreadsProp(_numThreads);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
return ParseParamsFromPROPVARIANT(name, value);
|
||||||
int index = FindPropIdExact(realName);
|
|
||||||
if (index < 0)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
const CNameToPropID &nameToPropID = g_NameToPropID[index];
|
|
||||||
prop.Id = nameToPropID.PropID;
|
|
||||||
if (!ConvertProperty(value, nameToPropID.VarType, prop.Value))
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
oneMethodInfo.Props.Add(prop);
|
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,83 +3,61 @@
|
|||||||
#ifndef __HANDLER_OUT_H
|
#ifndef __HANDLER_OUT_H
|
||||||
#define __HANDLER_OUT_H
|
#define __HANDLER_OUT_H
|
||||||
|
|
||||||
#include "../../../Common/MyString.h"
|
|
||||||
#include "../../Common/MethodProps.h"
|
#include "../../Common/MethodProps.h"
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
|
|
||||||
struct COneMethodInfo
|
class CMultiMethodProps
|
||||||
{
|
|
||||||
CObjectVector<CProp> Props;
|
|
||||||
UString MethodName;
|
|
||||||
|
|
||||||
bool IsLzma() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class COutHandler
|
|
||||||
{
|
{
|
||||||
|
UInt32 _level;
|
||||||
public:
|
public:
|
||||||
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
|
|
||||||
|
|
||||||
HRESULT SetSolidSettings(const UString &s);
|
|
||||||
HRESULT SetSolidSettings(const PROPVARIANT &value);
|
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
UInt32 _numThreads;
|
UInt32 _numThreads;
|
||||||
|
UInt32 _numProcessors;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UInt32 _crcSize;
|
UInt32 _crcSize;
|
||||||
|
|
||||||
CObjectVector<COneMethodInfo> _methods;
|
CObjectVector<COneMethodInfo> _methods;
|
||||||
bool _removeSfxBlock;
|
COneMethodInfo _filterMethod;
|
||||||
|
|
||||||
UInt64 _numSolidFiles;
|
|
||||||
UInt64 _numSolidBytes;
|
|
||||||
bool _numSolidBytesDefined;
|
|
||||||
bool _solidExtension;
|
|
||||||
|
|
||||||
bool _compressHeaders;
|
|
||||||
bool _encryptHeadersSpecified;
|
|
||||||
bool _encryptHeaders;
|
|
||||||
|
|
||||||
bool WriteCTime;
|
|
||||||
bool WriteATime;
|
|
||||||
bool WriteMTime;
|
|
||||||
|
|
||||||
bool _autoFilter;
|
bool _autoFilter;
|
||||||
UInt32 _level;
|
|
||||||
|
|
||||||
bool _volumeMode;
|
void SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo
|
||||||
|
|
||||||
HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);
|
|
||||||
HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);
|
|
||||||
|
|
||||||
void SetCompressionMethod2(COneMethodInfo &oneMethodInfo
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
, UInt32 numThreads
|
, UInt32 numThreads
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
|
int GetNumEmptyMethods() const
|
||||||
void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
|
|
||||||
void InitSolid()
|
|
||||||
{
|
{
|
||||||
InitSolidFiles();
|
int i;
|
||||||
InitSolidSize();
|
for (i = 0; i < _methods.Size(); i++)
|
||||||
_solidExtension = false;
|
if (!_methods[i].IsEmpty())
|
||||||
_numSolidBytesDefined = false;
|
break;
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetLevel() const { return _level == (UInt32)(UInt32)-1 ? 5 : (int)_level; }
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
COutHandler() { Init(); }
|
CMultiMethodProps() { Init(); }
|
||||||
|
HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
|
||||||
|
};
|
||||||
|
|
||||||
void BeforeSetProperty();
|
class CSingleMethodProps: public CMethodProps
|
||||||
|
{
|
||||||
|
UInt32 _level;
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
public:
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
UInt32 _numThreads;
|
||||||
|
UInt32 _numProcessors;
|
||||||
|
#endif
|
||||||
|
|
||||||
UInt32 minNumber;
|
CSingleMethodProps() { Init(); }
|
||||||
UInt32 numProcessors;
|
int GetLevel() const { return _level == (UInt32)(UInt32)-1 ? 5 : (int)_level; }
|
||||||
UInt32 mainDicSize;
|
HRESULT SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
|
||||||
UInt32 mainDicMethodIndex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,10 @@ STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSi
|
|||||||
{
|
{
|
||||||
UInt32 realProcessedSize;
|
UInt32 realProcessedSize;
|
||||||
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
||||||
|
/*
|
||||||
if (size > 0 && realProcessedSize == 0)
|
if (size > 0 && realProcessedSize == 0)
|
||||||
_wasFinished = true;
|
_wasFinished = true;
|
||||||
|
*/
|
||||||
_size += realProcessedSize;
|
_size += realProcessedSize;
|
||||||
_crc = CrcUpdate(_crc, data, realProcessedSize);
|
_crc = CrcUpdate(_crc, data, realProcessedSize);
|
||||||
if(processedSize != NULL)
|
if(processedSize != NULL)
|
||||||
|
|||||||
@@ -49,19 +49,19 @@ private:
|
|||||||
CMyComPtr<IInStream> _stream;
|
CMyComPtr<IInStream> _stream;
|
||||||
UInt64 _size;
|
UInt64 _size;
|
||||||
UInt32 _crc;
|
UInt32 _crc;
|
||||||
bool _wasFinished;
|
// bool _wasFinished;
|
||||||
public:
|
public:
|
||||||
void SetStream(IInStream *stream) { _stream = stream; }
|
void SetStream(IInStream *stream) { _stream = stream; }
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
_size = 0;
|
_size = 0;
|
||||||
_wasFinished = false;
|
// _wasFinished = false;
|
||||||
_crc = CRC_INIT_VAL;
|
_crc = CRC_INIT_VAL;
|
||||||
}
|
}
|
||||||
void ReleaseStream() { _stream.Release(); }
|
void ReleaseStream() { _stream.Release(); }
|
||||||
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
|
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
|
||||||
UInt64 GetSize() const { return _size; }
|
UInt64 GetSize() const { return _size; }
|
||||||
bool WasFinished() const { return _wasFinished; }
|
// bool WasFinished() const { return _wasFinished; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "../../../../C/Types.h"
|
||||||
|
|
||||||
#include "ItemNameUtils.h"
|
#include "ItemNameUtils.h"
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
@@ -29,8 +31,8 @@ UString GetOSName2(const UString &name)
|
|||||||
if (name.IsEmpty())
|
if (name.IsEmpty())
|
||||||
return UString();
|
return UString();
|
||||||
UString newName = GetOSName(name);
|
UString newName = GetOSName(name);
|
||||||
if (newName[newName.Length() - 1] == kOSDirDelimiter)
|
if (newName.Back() == kOSDirDelimiter)
|
||||||
newName.Delete(newName.Length() - 1);
|
newName.DeleteBack();
|
||||||
return newName;
|
return newName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,72 +6,61 @@
|
|||||||
|
|
||||||
STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||||
{
|
{
|
||||||
if(processedSize != NULL)
|
if (processedSize)
|
||||||
*processedSize = 0;
|
*processedSize = 0;
|
||||||
while(_streamIndex < Streams.Size() && size > 0)
|
if (size == 0)
|
||||||
|
return S_OK;
|
||||||
|
if (_pos >= _totalLength)
|
||||||
|
return (_pos == _totalLength) ? S_OK : E_FAIL;
|
||||||
|
|
||||||
{
|
{
|
||||||
CSubStreamInfo &s = Streams[_streamIndex];
|
int left = 0, mid = _streamIndex, right = Streams.Size();
|
||||||
if (_pos == s.Size)
|
for (;;)
|
||||||
{
|
{
|
||||||
_streamIndex++;
|
CSubStreamInfo &m = Streams[mid];
|
||||||
_pos = 0;
|
if (_pos < m.GlobalOffset)
|
||||||
continue;
|
right = mid;
|
||||||
|
else if (_pos >= m.GlobalOffset + m.Size)
|
||||||
|
left = mid + 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_streamIndex = mid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mid = (left + right) / 2;
|
||||||
}
|
}
|
||||||
RINOK(s.Stream->Seek(s.Pos + _pos, STREAM_SEEK_SET, 0));
|
_streamIndex = mid;
|
||||||
UInt32 sizeToRead = UInt32(MyMin((UInt64)size, s.Size - _pos));
|
|
||||||
UInt32 realProcessed;
|
|
||||||
HRESULT result = s.Stream->Read(data, sizeToRead, &realProcessed);
|
|
||||||
data = (void *)((Byte *)data + realProcessed);
|
|
||||||
size -= realProcessed;
|
|
||||||
if(processedSize != NULL)
|
|
||||||
*processedSize += realProcessed;
|
|
||||||
_pos += realProcessed;
|
|
||||||
_seekPos += realProcessed;
|
|
||||||
RINOK(result);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return S_OK;
|
|
||||||
|
CSubStreamInfo &s = Streams[_streamIndex];
|
||||||
|
UInt64 localPos = _pos - s.GlobalOffset;
|
||||||
|
if (localPos != s.LocalPos)
|
||||||
|
{
|
||||||
|
RINOK(s.Stream->Seek(localPos, STREAM_SEEK_SET, &s.LocalPos));
|
||||||
|
}
|
||||||
|
UInt64 rem = s.Size - localPos;
|
||||||
|
if (size > rem)
|
||||||
|
size = (UInt32)rem;
|
||||||
|
HRESULT result = s.Stream->Read(data, size, &size);
|
||||||
|
_pos += size;
|
||||||
|
s.LocalPos += size;
|
||||||
|
if (processedSize)
|
||||||
|
*processedSize = size;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin,
|
STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
|
||||||
UInt64 *newPosition)
|
|
||||||
{
|
{
|
||||||
UInt64 newPos;
|
|
||||||
switch(seekOrigin)
|
switch(seekOrigin)
|
||||||
{
|
{
|
||||||
case STREAM_SEEK_SET:
|
case STREAM_SEEK_SET: _pos = offset; break;
|
||||||
newPos = offset;
|
case STREAM_SEEK_CUR: _pos = _pos + offset; break;
|
||||||
break;
|
case STREAM_SEEK_END: _pos = _totalLength + offset; break;
|
||||||
case STREAM_SEEK_CUR:
|
default: return STG_E_INVALIDFUNCTION;
|
||||||
newPos = _seekPos + offset;
|
|
||||||
break;
|
|
||||||
case STREAM_SEEK_END:
|
|
||||||
newPos = _totalLength + offset;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return STG_E_INVALIDFUNCTION;
|
|
||||||
}
|
}
|
||||||
_seekPos = 0;
|
if (newPosition != 0)
|
||||||
for (_streamIndex = 0; _streamIndex < Streams.Size(); _streamIndex++)
|
*newPosition = _pos;
|
||||||
{
|
return S_OK;
|
||||||
UInt64 size = Streams[_streamIndex].Size;
|
|
||||||
if (newPos < _seekPos + size)
|
|
||||||
{
|
|
||||||
_pos = newPos - _seekPos;
|
|
||||||
_seekPos += _pos;
|
|
||||||
if (newPosition != 0)
|
|
||||||
*newPosition = newPos;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
_seekPos += size;
|
|
||||||
}
|
|
||||||
if (newPos == _seekPos)
|
|
||||||
{
|
|
||||||
if (newPosition != 0)
|
|
||||||
*newPosition = newPos;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,36 +1,44 @@
|
|||||||
// MultiStream.h
|
// MultiStream.h
|
||||||
|
|
||||||
#ifndef __MULTISTREAM_H
|
#ifndef __MULTI_STREAM_H
|
||||||
#define __MULTISTREAM_H
|
#define __MULTI_STREAM_H
|
||||||
|
|
||||||
#include "../../../Common/MyCom.h"
|
#include "../../../Common/MyCom.h"
|
||||||
#include "../../../Common/MyVector.h"
|
#include "../../../Common/MyVector.h"
|
||||||
#include "../../Archive/IArchive.h"
|
|
||||||
|
#include "../../IStream.h"
|
||||||
|
|
||||||
class CMultiStream:
|
class CMultiStream:
|
||||||
public IInStream,
|
public IInStream,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
int _streamIndex;
|
|
||||||
UInt64 _pos;
|
UInt64 _pos;
|
||||||
UInt64 _seekPos;
|
|
||||||
UInt64 _totalLength;
|
UInt64 _totalLength;
|
||||||
|
int _streamIndex;
|
||||||
public:
|
public:
|
||||||
struct CSubStreamInfo
|
struct CSubStreamInfo
|
||||||
{
|
{
|
||||||
CMyComPtr<IInStream> Stream;
|
CMyComPtr<IInStream> Stream;
|
||||||
UInt64 Pos;
|
|
||||||
UInt64 Size;
|
UInt64 Size;
|
||||||
|
UInt64 GlobalOffset;
|
||||||
|
UInt64 LocalPos;
|
||||||
};
|
};
|
||||||
CObjectVector<CSubStreamInfo> Streams;
|
CObjectVector<CSubStreamInfo> Streams;
|
||||||
void Init()
|
|
||||||
|
HRESULT Init()
|
||||||
{
|
{
|
||||||
_streamIndex = 0;
|
UInt64 total = 0;
|
||||||
_pos = 0;
|
|
||||||
_seekPos = 0;
|
|
||||||
_totalLength = 0;
|
|
||||||
for (int i = 0; i < Streams.Size(); i++)
|
for (int i = 0; i < Streams.Size(); i++)
|
||||||
_totalLength += Streams[i].Size;
|
{
|
||||||
|
CSubStreamInfo &s = Streams[i];
|
||||||
|
s.GlobalOffset = total;
|
||||||
|
total += Streams[i].Size;
|
||||||
|
RINOK(s.Stream->Seek(0, STREAM_SEEK_CUR, &s.LocalPos));
|
||||||
|
}
|
||||||
|
_totalLength = total;
|
||||||
|
_pos = 0;
|
||||||
|
_streamIndex = 0;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
MY_UNKNOWN_IMP1(IInStream)
|
MY_UNKNOWN_IMP1(IInStream)
|
||||||
|
|||||||
@@ -1,177 +1,3 @@
|
|||||||
// ParseProperties.cpp
|
// ParseProperties.cpp
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "ParseProperties.h"
|
|
||||||
|
|
||||||
#include "Common/StringToInt.h"
|
|
||||||
#include "Common/MyCom.h"
|
|
||||||
|
|
||||||
HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
|
|
||||||
{
|
|
||||||
if (prop.vt == VT_UI4)
|
|
||||||
{
|
|
||||||
if (!name.IsEmpty())
|
|
||||||
return E_INVALIDARG;
|
|
||||||
resValue = prop.ulVal;
|
|
||||||
}
|
|
||||||
else if (prop.vt == VT_EMPTY)
|
|
||||||
{
|
|
||||||
if(!name.IsEmpty())
|
|
||||||
{
|
|
||||||
const wchar_t *start = name;
|
|
||||||
const wchar_t *end;
|
|
||||||
UInt64 v = ConvertStringToUInt64(start, &end);
|
|
||||||
if (end - start != name.Length())
|
|
||||||
return E_INVALIDARG;
|
|
||||||
resValue = (UInt32)v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return E_INVALIDARG;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const int kLogarithmicSizeLimit = 32;
|
|
||||||
static const wchar_t kByteSymbol = L'B';
|
|
||||||
static const wchar_t kKiloByteSymbol = L'K';
|
|
||||||
static const wchar_t kMegaByteSymbol = L'M';
|
|
||||||
|
|
||||||
HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize)
|
|
||||||
{
|
|
||||||
UString srcString = srcStringSpec;
|
|
||||||
srcString.MakeUpper();
|
|
||||||
|
|
||||||
const wchar_t *start = srcString;
|
|
||||||
const wchar_t *end;
|
|
||||||
UInt64 number = ConvertStringToUInt64(start, &end);
|
|
||||||
int numDigits = (int)(end - start);
|
|
||||||
if (numDigits == 0 || srcString.Length() > numDigits + 1)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
if (srcString.Length() == numDigits)
|
|
||||||
{
|
|
||||||
if (number >= kLogarithmicSizeLimit)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
dicSize = (UInt32)1 << (int)number;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
switch (srcString[numDigits])
|
|
||||||
{
|
|
||||||
case kByteSymbol:
|
|
||||||
if (number >= ((UInt64)1 << kLogarithmicSizeLimit))
|
|
||||||
return E_INVALIDARG;
|
|
||||||
dicSize = (UInt32)number;
|
|
||||||
break;
|
|
||||||
case kKiloByteSymbol:
|
|
||||||
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))
|
|
||||||
return E_INVALIDARG;
|
|
||||||
dicSize = (UInt32)(number << 10);
|
|
||||||
break;
|
|
||||||
case kMegaByteSymbol:
|
|
||||||
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))
|
|
||||||
return E_INVALIDARG;
|
|
||||||
dicSize = (UInt32)(number << 20);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
|
|
||||||
{
|
|
||||||
if (name.IsEmpty())
|
|
||||||
{
|
|
||||||
if (prop.vt == VT_UI4)
|
|
||||||
{
|
|
||||||
UInt32 logDicSize = prop.ulVal;
|
|
||||||
if (logDicSize >= 32)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
resValue = (UInt32)1 << logDicSize;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
if (prop.vt == VT_BSTR)
|
|
||||||
return ParsePropDictionaryValue(prop.bstrVal, resValue);
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
return ParsePropDictionaryValue(name, resValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StringToBool(const UString &s, bool &res)
|
|
||||||
{
|
|
||||||
if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0 || s.Compare(L"+") == 0)
|
|
||||||
{
|
|
||||||
res = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (s.CompareNoCase(L"OFF") == 0 || s.Compare(L"-") == 0)
|
|
||||||
{
|
|
||||||
res = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
|
|
||||||
{
|
|
||||||
switch(value.vt)
|
|
||||||
{
|
|
||||||
case VT_EMPTY:
|
|
||||||
dest = true;
|
|
||||||
return S_OK;
|
|
||||||
case VT_BOOL:
|
|
||||||
dest = (value.boolVal != VARIANT_FALSE);
|
|
||||||
return S_OK;
|
|
||||||
/*
|
|
||||||
case VT_UI4:
|
|
||||||
dest = (value.ulVal != 0);
|
|
||||||
break;
|
|
||||||
*/
|
|
||||||
case VT_BSTR:
|
|
||||||
return StringToBool(value.bstrVal, dest) ? S_OK : E_INVALIDARG;
|
|
||||||
}
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ParseStringToUInt32(const UString &srcString, UInt32 &number)
|
|
||||||
{
|
|
||||||
const wchar_t *start = srcString;
|
|
||||||
const wchar_t *end;
|
|
||||||
UInt64 number64 = ConvertStringToUInt64(start, &end);
|
|
||||||
if (number64 > 0xFFFFFFFF)
|
|
||||||
{
|
|
||||||
number = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
number = (UInt32)number64;
|
|
||||||
return (int)(end - start);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
|
|
||||||
{
|
|
||||||
if (name.IsEmpty())
|
|
||||||
{
|
|
||||||
switch(prop.vt)
|
|
||||||
{
|
|
||||||
case VT_UI4:
|
|
||||||
numThreads = prop.ulVal;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
bool val;
|
|
||||||
RINOK(SetBoolProperty(val, prop));
|
|
||||||
numThreads = (val ? defaultNumThreads : 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UInt32 number;
|
|
||||||
int index = ParseStringToUInt32(name, number);
|
|
||||||
if (index != name.Length())
|
|
||||||
return E_INVALIDARG;
|
|
||||||
numThreads = number;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,18 +1,6 @@
|
|||||||
// ParseProperties.h
|
// ParseProperties.h
|
||||||
|
|
||||||
#ifndef __PARSEPROPERTIES_H
|
#ifndef __PARSE_PROPERTIES_H
|
||||||
#define __PARSEPROPERTIES_H
|
#define __PARSE_PROPERTIES_H
|
||||||
|
|
||||||
#include "Common/MyString.h"
|
|
||||||
#include "Common/Types.h"
|
|
||||||
|
|
||||||
HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
|
|
||||||
HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize);
|
|
||||||
HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
|
|
||||||
|
|
||||||
bool StringToBool(const UString &s, bool &res);
|
|
||||||
HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value);
|
|
||||||
int ParseStringToUInt32(const UString &srcString, UInt32 &number);
|
|
||||||
HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "Common/ComTry.h"
|
#include "Common/ComTry.h"
|
||||||
#include "Common/StringToInt.h"
|
|
||||||
#include "Common/StringConvert.h"
|
#include "Common/StringConvert.h"
|
||||||
|
#include "Common/StringToInt.h"
|
||||||
|
|
||||||
#include "Windows/PropVariant.h"
|
#include "Windows/PropVariant.h"
|
||||||
#include "Windows/Time.h"
|
#include "Windows/Time.h"
|
||||||
@@ -25,10 +25,10 @@ namespace NFileHeader
|
|||||||
{
|
{
|
||||||
namespace NMagic
|
namespace NMagic
|
||||||
{
|
{
|
||||||
extern const char *kMagic1 = "070701";
|
const char *kMagic1 = "070701";
|
||||||
extern const char *kMagic2 = "070702";
|
const char *kMagic2 = "070702";
|
||||||
extern const char *kMagic3 = "070707";
|
const char *kMagic3 = "070707";
|
||||||
extern const char *kEndName = "TRAILER!!!";
|
const char *kEndName = "TRAILER!!!";
|
||||||
|
|
||||||
const Byte kMagicForRecord2[2] = { 0xC7, 0x71 };
|
const Byte kMagicForRecord2[2] = { 0xC7, 0x71 };
|
||||||
}
|
}
|
||||||
|
|||||||
644
CPP/7zip/Archive/CramfsHandler.cpp
Executable file
@@ -0,0 +1,644 @@
|
|||||||
|
// CramfsHandler.cpp
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "../../../C/7zCrc.h"
|
||||||
|
#include "../../../C/CpuArch.h"
|
||||||
|
#include "../../../C/Alloc.h"
|
||||||
|
|
||||||
|
#include "Common/ComTry.h"
|
||||||
|
#include "Common/StringConvert.h"
|
||||||
|
|
||||||
|
#include "Windows/PropVariantUtils.h"
|
||||||
|
|
||||||
|
#include "../Common/LimitedStreams.h"
|
||||||
|
#include "../Common/ProgressUtils.h"
|
||||||
|
#include "../Common/RegisterArc.h"
|
||||||
|
#include "../Common/StreamObjects.h"
|
||||||
|
#include "../Common/StreamUtils.h"
|
||||||
|
|
||||||
|
#include "../Compress/CopyCoder.h"
|
||||||
|
#include "../Compress/ZlibDecoder.h"
|
||||||
|
|
||||||
|
namespace NArchive {
|
||||||
|
namespace NCramfs {
|
||||||
|
|
||||||
|
#define SIGNATURE { 'C','o','m','p','r','e','s','s','e','d',' ','R','O','M','F','S' }
|
||||||
|
|
||||||
|
static const UInt32 kSignatureSize = 16;
|
||||||
|
static const char kSignature[kSignatureSize] = SIGNATURE;
|
||||||
|
|
||||||
|
static const UInt32 kArcSizeMax = (256 + 16) << 20;
|
||||||
|
static const UInt32 kNumFilesMax = (1 << 19);
|
||||||
|
static const unsigned kNumDirLevelsMax = (1 << 8);
|
||||||
|
|
||||||
|
static const UInt32 kHeaderSize = 0x40;
|
||||||
|
static const unsigned kHeaderNameSize = 16;
|
||||||
|
static const UInt32 kNodeSize = 12;
|
||||||
|
|
||||||
|
static const UInt32 kFlag_FsVer2 = (1 << 0);
|
||||||
|
|
||||||
|
static const CUInt32PCharPair k_Flags[] =
|
||||||
|
{
|
||||||
|
{ 0, "Ver2" },
|
||||||
|
{ 1, "SortedDirs" },
|
||||||
|
{ 8, "Holes" },
|
||||||
|
{ 9, "WrongSignature" },
|
||||||
|
{ 10, "ShiftedRootOffset" }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned kBlockSizeLog = 12;
|
||||||
|
static const UInt32 kBlockSize = 1 << kBlockSizeLog;
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct CNode
|
||||||
|
{
|
||||||
|
UInt16 Mode;
|
||||||
|
UInt16 Uid;
|
||||||
|
UInt32 Size;
|
||||||
|
Byte Gid;
|
||||||
|
UInt32 NameLen;
|
||||||
|
UInt32 Offset;
|
||||||
|
|
||||||
|
void Parse(const Byte *p)
|
||||||
|
{
|
||||||
|
Mode = GetUi16(p);
|
||||||
|
Uid = GetUi16(p + 2);
|
||||||
|
Size = Get32(p + 4) & 0xFFFFFF;
|
||||||
|
Gid = p[7];
|
||||||
|
NameLen = p[8] & 0x3F;
|
||||||
|
Offset = Get32(p + 8) >> 6;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define Get32(p) (be ? GetBe32(p) : GetUi32(p))
|
||||||
|
|
||||||
|
static UInt32 GetMode(const Byte *p, bool be) { return be ? GetBe16(p) : GetUi16(p); }
|
||||||
|
static bool IsDir(const Byte *p, bool be) { return (GetMode(p, be) & 0xF000) == 0x4000; }
|
||||||
|
|
||||||
|
static UInt32 GetSize(const Byte *p, bool be)
|
||||||
|
{
|
||||||
|
if (be)
|
||||||
|
return GetBe32(p + 4) >> 8;
|
||||||
|
else
|
||||||
|
return GetUi32(p + 4) & 0xFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 GetNameLen(const Byte *p, bool be)
|
||||||
|
{
|
||||||
|
if (be)
|
||||||
|
return (p[8] & 0xFC);
|
||||||
|
else
|
||||||
|
return (p[8] & 0x3F) << 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UInt32 GetOffset(const Byte *p, bool be)
|
||||||
|
{
|
||||||
|
if (be)
|
||||||
|
return (GetBe32(p + 8) & 0x03FFFFFF) << 2;
|
||||||
|
else
|
||||||
|
return GetUi32(p + 8) >> 6 << 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CItem
|
||||||
|
{
|
||||||
|
UInt32 Offset;
|
||||||
|
int Parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CHeader
|
||||||
|
{
|
||||||
|
bool be;
|
||||||
|
UInt32 Size;
|
||||||
|
UInt32 Flags;
|
||||||
|
// UInt32 Future;
|
||||||
|
UInt32 Crc;
|
||||||
|
// UInt32 Edition;
|
||||||
|
UInt32 NumBlocks;
|
||||||
|
UInt32 NumFiles;
|
||||||
|
char Name[kHeaderNameSize];
|
||||||
|
|
||||||
|
bool Parse(const Byte *p)
|
||||||
|
{
|
||||||
|
if (memcmp(p + 16, kSignature, kSignatureSize) != 0)
|
||||||
|
return false;
|
||||||
|
switch(GetUi32(p))
|
||||||
|
{
|
||||||
|
case 0x28CD3D45: be = false; break;
|
||||||
|
case 0x453DCD28: be = true; break;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
Size = Get32(p + 4);
|
||||||
|
Flags = Get32(p + 8);
|
||||||
|
// Future = Get32(p + 0xC);
|
||||||
|
Crc = Get32(p + 0x20);
|
||||||
|
// Edition = Get32(p + 0x24);
|
||||||
|
NumBlocks = Get32(p + 0x28);
|
||||||
|
NumFiles = Get32(p + 0x2C);
|
||||||
|
memcpy(Name, p + 0x30, kHeaderNameSize);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsVer2() const { return (Flags & kFlag_FsVer2) != 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class CHandler:
|
||||||
|
public IInArchive,
|
||||||
|
public IInArchiveGetStream,
|
||||||
|
public CMyUnknownImp
|
||||||
|
{
|
||||||
|
CRecordVector<CItem> _items;
|
||||||
|
CMyComPtr<IInStream> _stream;
|
||||||
|
Byte *_data;
|
||||||
|
UInt32 _size;
|
||||||
|
UInt32 _headersSize;
|
||||||
|
AString _errorMessage;
|
||||||
|
CHeader _h;
|
||||||
|
|
||||||
|
// Current file
|
||||||
|
|
||||||
|
NCompress::NZlib::CDecoder *_zlibDecoderSpec;
|
||||||
|
CMyComPtr<ICompressCoder> _zlibDecoder;
|
||||||
|
|
||||||
|
CBufInStream *_inStreamSpec;
|
||||||
|
CMyComPtr<ISequentialInStream> _inStream;
|
||||||
|
|
||||||
|
CBufPtrSeqOutStream *_outStreamSpec;
|
||||||
|
CMyComPtr<ISequentialOutStream> _outStream;
|
||||||
|
|
||||||
|
UInt32 _curBlocksOffset;
|
||||||
|
UInt32 _curNumBlocks;
|
||||||
|
|
||||||
|
HRESULT OpenDir(int parent, UInt32 baseOffsetBase, unsigned level);
|
||||||
|
HRESULT Open2(IInStream *inStream);
|
||||||
|
AString GetPath(int index) const;
|
||||||
|
bool GetPackSize(int index, UInt32 &res) const;
|
||||||
|
void Free();
|
||||||
|
public:
|
||||||
|
CHandler(): _data(0) {}
|
||||||
|
~CHandler() { Free(); }
|
||||||
|
MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
|
||||||
|
INTERFACE_IInArchive(;)
|
||||||
|
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
|
||||||
|
HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize);
|
||||||
|
};
|
||||||
|
|
||||||
|
static const STATPROPSTG kProps[] =
|
||||||
|
{
|
||||||
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
|
{ NULL, kpidIsDir, VT_BOOL},
|
||||||
|
{ NULL, kpidSize, VT_UI4},
|
||||||
|
{ NULL, kpidPackSize, VT_UI4},
|
||||||
|
{ NULL, kpidPosixAttrib, VT_UI4}
|
||||||
|
// { NULL, kpidOffset, VT_UI4}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const STATPROPSTG kArcProps[] =
|
||||||
|
{
|
||||||
|
{ NULL, kpidName, VT_BSTR},
|
||||||
|
{ NULL, kpidBigEndian, VT_BOOL},
|
||||||
|
{ NULL, kpidCharacts, VT_BSTR},
|
||||||
|
{ NULL, kpidPhySize, VT_UI4},
|
||||||
|
{ NULL, kpidHeadersSize, VT_UI4},
|
||||||
|
{ NULL, kpidNumSubFiles, VT_UI4},
|
||||||
|
{ NULL, kpidNumBlocks, VT_UI4}
|
||||||
|
};
|
||||||
|
|
||||||
|
IMP_IInArchive_Props
|
||||||
|
IMP_IInArchive_ArcProps
|
||||||
|
|
||||||
|
HRESULT CHandler::OpenDir(int parent, UInt32 baseOffset, unsigned level)
|
||||||
|
{
|
||||||
|
const Byte *p = _data + baseOffset;
|
||||||
|
bool be = _h.be;
|
||||||
|
if (!IsDir(p, be))
|
||||||
|
return S_OK;
|
||||||
|
UInt32 offset = GetOffset(p, be);
|
||||||
|
UInt32 size = GetSize(p, be);
|
||||||
|
if (offset == 0 && size == 0)
|
||||||
|
return S_OK;
|
||||||
|
UInt32 end = offset + size;
|
||||||
|
if (offset < kHeaderSize || end > _size || level > kNumDirLevelsMax)
|
||||||
|
return S_FALSE;
|
||||||
|
if (end > _headersSize)
|
||||||
|
_headersSize = end;
|
||||||
|
|
||||||
|
int startIndex = _items.Size();
|
||||||
|
|
||||||
|
while (size != 0)
|
||||||
|
{
|
||||||
|
if (size < kNodeSize || (UInt32)_items.Size() >= kNumFilesMax)
|
||||||
|
return S_FALSE;
|
||||||
|
CItem item;
|
||||||
|
item.Parent = parent;
|
||||||
|
item.Offset = offset;
|
||||||
|
_items.Add(item);
|
||||||
|
UInt32 nodeLen = kNodeSize + GetNameLen(_data + offset, be);
|
||||||
|
if (size < nodeLen)
|
||||||
|
return S_FALSE;
|
||||||
|
offset += nodeLen;
|
||||||
|
size -= nodeLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int endIndex = _items.Size();
|
||||||
|
for (int i = startIndex; i < endIndex; i++)
|
||||||
|
{
|
||||||
|
RINOK(OpenDir(i, _items[i].Offset, level + 1));
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CHandler::Open2(IInStream *inStream)
|
||||||
|
{
|
||||||
|
Byte buf[kHeaderSize];
|
||||||
|
RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize));
|
||||||
|
if (!_h.Parse(buf))
|
||||||
|
return S_FALSE;
|
||||||
|
if (_h.IsVer2())
|
||||||
|
{
|
||||||
|
if (_h.Size < kHeaderSize || _h.Size > kArcSizeMax || _h.NumFiles > kNumFilesMax)
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UInt64 size;
|
||||||
|
RINOK(inStream->Seek(0, STREAM_SEEK_END, &size));
|
||||||
|
if (size > kArcSizeMax)
|
||||||
|
return S_FALSE;
|
||||||
|
_h.Size = (UInt32)size;
|
||||||
|
RINOK(inStream->Seek(kHeaderSize, STREAM_SEEK_SET, NULL));
|
||||||
|
}
|
||||||
|
_data = (Byte *)MidAlloc(_h.Size);
|
||||||
|
if (_data == 0)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
memcpy(_data, buf, kHeaderSize);
|
||||||
|
size_t processed = _h.Size - kHeaderSize;
|
||||||
|
RINOK(ReadStream(inStream, _data + kHeaderSize, &processed));
|
||||||
|
if (processed < kNodeSize)
|
||||||
|
return S_FALSE;
|
||||||
|
_size = kHeaderSize + (UInt32)processed;
|
||||||
|
if (_size != _h.Size)
|
||||||
|
_errorMessage = "Unexpected end of archive";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetUi32(_data + 0x20, 0);
|
||||||
|
if (_h.IsVer2())
|
||||||
|
if (CrcCalc(_data, _h.Size) != _h.Crc)
|
||||||
|
_errorMessage = "CRC error";
|
||||||
|
}
|
||||||
|
if (_h.IsVer2())
|
||||||
|
_items.Reserve(_h.NumFiles - 1);
|
||||||
|
return OpenDir(-1, kHeaderSize, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
AString CHandler::GetPath(int index) const
|
||||||
|
{
|
||||||
|
unsigned len = 0;
|
||||||
|
int indexMem = index;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
const CItem &item = _items[index];
|
||||||
|
index = item.Parent;
|
||||||
|
const Byte *p = _data + item.Offset;
|
||||||
|
unsigned size = GetNameLen(p, _h.be);
|
||||||
|
p += kNodeSize;
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < size && p[i]; i++);
|
||||||
|
len += i + 1;
|
||||||
|
}
|
||||||
|
while (index >= 0);
|
||||||
|
len--;
|
||||||
|
|
||||||
|
AString path;
|
||||||
|
char *dest = path.GetBuffer(len) + len;
|
||||||
|
index = indexMem;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
const CItem &item = _items[index];
|
||||||
|
index = item.Parent;
|
||||||
|
const Byte *p = _data + item.Offset;
|
||||||
|
unsigned size = GetNameLen(p, _h.be);
|
||||||
|
p += kNodeSize;
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < size && p[i]; i++);
|
||||||
|
dest -= i;
|
||||||
|
memcpy(dest, p, i);
|
||||||
|
if (index < 0)
|
||||||
|
break;
|
||||||
|
*(--dest) = CHAR_PATH_SEPARATOR;
|
||||||
|
}
|
||||||
|
path.ReleaseBuffer(len);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CHandler::GetPackSize(int index, UInt32 &res) const
|
||||||
|
{
|
||||||
|
const CItem &item = _items[index];
|
||||||
|
const Byte *p = _data + item.Offset;
|
||||||
|
bool be = _h.be;
|
||||||
|
UInt32 offset = GetOffset(p, be);
|
||||||
|
if (offset < kHeaderSize)
|
||||||
|
return false;
|
||||||
|
UInt32 numBlocks = (GetSize(p, be) + kBlockSize - 1) >> kBlockSizeLog;
|
||||||
|
UInt32 start = offset + numBlocks * 4;
|
||||||
|
if (start > _size)
|
||||||
|
return false;
|
||||||
|
UInt32 end = Get32(_data + start - 4);
|
||||||
|
if (end < start)
|
||||||
|
return false;
|
||||||
|
res = end - start;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback * /* callback */)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
RINOK(Open2(stream));
|
||||||
|
_stream = stream;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHandler::Free()
|
||||||
|
{
|
||||||
|
MidFree(_data);
|
||||||
|
_data = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Close()
|
||||||
|
{
|
||||||
|
_headersSize = 0;
|
||||||
|
_items.Clear();
|
||||||
|
_stream.Release();
|
||||||
|
_errorMessage.Empty();
|
||||||
|
Free();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||||
|
{
|
||||||
|
*numItems = _items.Size();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
NWindows::NCOM::CPropVariant prop;
|
||||||
|
switch(propID)
|
||||||
|
{
|
||||||
|
case kpidName:
|
||||||
|
{
|
||||||
|
char dest[kHeaderNameSize + 4];
|
||||||
|
memcpy(dest, _h.Name, kHeaderNameSize);
|
||||||
|
dest[kHeaderNameSize] = 0;
|
||||||
|
prop = dest;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kpidBigEndian: prop = _h.be; break;
|
||||||
|
case kpidCharacts: FLAGS_TO_PROP(k_Flags, _h.Flags, prop); break;
|
||||||
|
case kpidNumBlocks: if (_h.IsVer2()) prop = _h.NumBlocks; break;
|
||||||
|
case kpidNumSubFiles: if (_h.IsVer2()) prop = _h.NumFiles; break;
|
||||||
|
case kpidPhySize: if (_h.IsVer2()) prop = _h.Size; break;
|
||||||
|
case kpidHeadersSize: prop = _headersSize; break;
|
||||||
|
case kpidError: if (!_errorMessage.IsEmpty()) prop = _errorMessage; break;
|
||||||
|
}
|
||||||
|
prop.Detach(value);
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
NWindows::NCOM::CPropVariant prop;
|
||||||
|
const CItem &item = _items[index];
|
||||||
|
const Byte *p = _data + item.Offset;
|
||||||
|
bool be = _h.be;
|
||||||
|
bool isDir = IsDir(p, be);
|
||||||
|
switch(propID)
|
||||||
|
{
|
||||||
|
case kpidPath: prop = MultiByteToUnicodeString(GetPath(index), CP_OEMCP); break;
|
||||||
|
case kpidIsDir: prop = isDir; break;
|
||||||
|
// case kpidOffset: prop = (UInt32)GetOffset(p, be); break;
|
||||||
|
case kpidSize: if (!isDir) prop = GetSize(p, be); break;
|
||||||
|
case kpidPackSize:
|
||||||
|
if (!isDir)
|
||||||
|
{
|
||||||
|
UInt32 size;
|
||||||
|
if (GetPackSize(index, size))
|
||||||
|
prop = size;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case kpidPosixAttrib: prop = (UInt32)GetMode(p, be); break;
|
||||||
|
}
|
||||||
|
prop.Detach(value);
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
class CCramfsInStream: public CCachedInStream
|
||||||
|
{
|
||||||
|
HRESULT ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize);
|
||||||
|
public:
|
||||||
|
CHandler *Handler;
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT CCramfsInStream::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize)
|
||||||
|
{
|
||||||
|
return Handler->ReadBlock(blockIndex, dest, blockSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CHandler::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize)
|
||||||
|
{
|
||||||
|
if (!_zlibDecoder)
|
||||||
|
{
|
||||||
|
_zlibDecoderSpec = new NCompress::NZlib::CDecoder();
|
||||||
|
_zlibDecoder = _zlibDecoderSpec;
|
||||||
|
}
|
||||||
|
if (!_inStream)
|
||||||
|
{
|
||||||
|
_inStreamSpec = new CBufInStream();
|
||||||
|
_inStream = _inStreamSpec;
|
||||||
|
}
|
||||||
|
if (!_outStream)
|
||||||
|
{
|
||||||
|
_outStreamSpec = new CBufPtrSeqOutStream();
|
||||||
|
_outStream = _outStreamSpec;
|
||||||
|
}
|
||||||
|
bool be = _h.be;
|
||||||
|
const Byte *p = _data + (_curBlocksOffset + (UInt32)blockIndex * 4);
|
||||||
|
UInt32 start = (blockIndex == 0 ? _curBlocksOffset + _curNumBlocks * 4: Get32(p - 4));
|
||||||
|
UInt32 end = Get32(p);
|
||||||
|
if (end < start || end > _size)
|
||||||
|
return S_FALSE;
|
||||||
|
UInt32 inSize = end - start;
|
||||||
|
_inStreamSpec->Init(_data + start, inSize);
|
||||||
|
_outStreamSpec->Init(dest, blockSize);
|
||||||
|
RINOK(_zlibDecoder->Code(_inStream, _outStream, NULL, NULL, NULL));
|
||||||
|
return (_zlibDecoderSpec->GetInputProcessedSize() == inSize &&
|
||||||
|
_outStreamSpec->GetPos() == blockSize) ? S_OK : S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
|
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
bool allFilesMode = (numItems == (UInt32)-1);
|
||||||
|
if (allFilesMode)
|
||||||
|
numItems = _items.Size();
|
||||||
|
if (numItems == 0)
|
||||||
|
return S_OK;
|
||||||
|
bool be = _h.be;
|
||||||
|
UInt64 totalSize = 0;
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < numItems; i++)
|
||||||
|
{
|
||||||
|
const Byte *p = _data + _items[allFilesMode ? i : indices[i]].Offset;
|
||||||
|
if (!IsDir(p, be))
|
||||||
|
totalSize += GetSize(p, be);
|
||||||
|
}
|
||||||
|
extractCallback->SetTotal(totalSize);
|
||||||
|
|
||||||
|
UInt64 totalPackSize;
|
||||||
|
totalSize = totalPackSize = 0;
|
||||||
|
|
||||||
|
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
||||||
|
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||||
|
|
||||||
|
CLocalProgress *lps = new CLocalProgress;
|
||||||
|
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||||
|
lps->Init(extractCallback, false);
|
||||||
|
|
||||||
|
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
||||||
|
CMyComPtr<ISequentialInStream> inStream(streamSpec);
|
||||||
|
streamSpec->SetStream(_stream);
|
||||||
|
|
||||||
|
for (i = 0; i < numItems; i++)
|
||||||
|
{
|
||||||
|
lps->InSize = totalPackSize;
|
||||||
|
lps->OutSize = totalSize;
|
||||||
|
RINOK(lps->SetCur());
|
||||||
|
CMyComPtr<ISequentialOutStream> outStream;
|
||||||
|
Int32 askMode = testMode ?
|
||||||
|
NExtract::NAskMode::kTest :
|
||||||
|
NExtract::NAskMode::kExtract;
|
||||||
|
UInt32 index = allFilesMode ? i : indices[i];
|
||||||
|
const CItem &item = _items[index];
|
||||||
|
RINOK(extractCallback->GetStream(index, &outStream, askMode));
|
||||||
|
const Byte *p = _data + item.Offset;
|
||||||
|
|
||||||
|
if (IsDir(p, be))
|
||||||
|
{
|
||||||
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
UInt32 curSize = GetSize(p, be);
|
||||||
|
totalSize += curSize;
|
||||||
|
UInt32 packSize;
|
||||||
|
if (GetPackSize(index, packSize))
|
||||||
|
totalPackSize += packSize;
|
||||||
|
|
||||||
|
if (!testMode && !outStream)
|
||||||
|
continue;
|
||||||
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
|
||||||
|
UInt32 offset = GetOffset(p, be);
|
||||||
|
if (offset < kHeaderSize)
|
||||||
|
curSize = 0;
|
||||||
|
|
||||||
|
int res = NExtract::NOperationResult::kDataError;
|
||||||
|
{
|
||||||
|
CMyComPtr<ISequentialInStream> inSeqStream;
|
||||||
|
CMyComPtr<IInStream> inStream;
|
||||||
|
HRESULT hres = GetStream(index, &inSeqStream);
|
||||||
|
if (inSeqStream)
|
||||||
|
inSeqStream.QueryInterface(IID_IInStream, &inStream);
|
||||||
|
if (hres == E_OUTOFMEMORY)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
if (hres == S_FALSE || !inStream)
|
||||||
|
res = NExtract::NOperationResult::kUnSupportedMethod;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RINOK(hres);
|
||||||
|
if (inStream)
|
||||||
|
{
|
||||||
|
HRESULT hres = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
|
||||||
|
if (hres != S_OK && hres != S_FALSE)
|
||||||
|
{
|
||||||
|
RINOK(hres);
|
||||||
|
}
|
||||||
|
if (copyCoderSpec->TotalSize == curSize && hres == S_OK)
|
||||||
|
res = NExtract::NOperationResult::kOK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RINOK(extractCallback->SetOperationResult(res));
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
|
||||||
|
const CItem &item = _items[index];
|
||||||
|
const Byte *p = _data + item.Offset;
|
||||||
|
|
||||||
|
bool be = _h.be;
|
||||||
|
if (IsDir(p, be))
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
UInt32 size = GetSize(p, be);
|
||||||
|
UInt32 numBlocks = (size + kBlockSize - 1) >> kBlockSizeLog;
|
||||||
|
UInt32 offset = GetOffset(p, be);
|
||||||
|
if (offset < kHeaderSize)
|
||||||
|
{
|
||||||
|
if (offset != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
CBufInStream *streamSpec = new CBufInStream;
|
||||||
|
CMyComPtr<IInStream> streamTemp = streamSpec;
|
||||||
|
streamSpec->Init(NULL, 0);
|
||||||
|
*stream = streamTemp.Detach();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset + numBlocks * 4 > _size)
|
||||||
|
return S_FALSE;
|
||||||
|
UInt32 prev = offset;
|
||||||
|
for (UInt32 i = 0; i < numBlocks; i++)
|
||||||
|
{
|
||||||
|
UInt32 next = Get32(_data + offset + i * 4);
|
||||||
|
if (next < prev || next > _size)
|
||||||
|
return S_FALSE;
|
||||||
|
prev = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
CCramfsInStream *streamSpec = new CCramfsInStream;
|
||||||
|
CMyComPtr<IInStream> streamTemp = streamSpec;
|
||||||
|
_curNumBlocks = numBlocks;
|
||||||
|
_curBlocksOffset = offset;
|
||||||
|
streamSpec->Handler = this;
|
||||||
|
if (!streamSpec->Alloc(kBlockSizeLog, 21 - kBlockSizeLog))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
streamSpec->Init(size);
|
||||||
|
*stream = streamTemp.Detach();
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
static IInArchive *CreateArc() { return new NArchive::NCramfs::CHandler; }
|
||||||
|
|
||||||
|
static CArcInfo g_ArcInfo =
|
||||||
|
{ L"CramFS", L"cramfs", 0, 0xD3, SIGNATURE, kSignatureSize, false, CreateArc, 0 };
|
||||||
|
|
||||||
|
REGISTER_ARC(Cramfs)
|
||||||
|
|
||||||
|
}}
|
||||||
@@ -3,8 +3,6 @@
|
|||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "Common/ComTry.h"
|
#include "Common/ComTry.h"
|
||||||
#include "Common/Defs.h"
|
|
||||||
#include "Common/NewHandler.h"
|
|
||||||
#include "Common/StringConvert.h"
|
#include "Common/StringConvert.h"
|
||||||
#include "Common/StringToInt.h"
|
#include "Common/StringToInt.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,118 +1,3 @@
|
|||||||
// DeflateProps.cpp
|
// DeflateProps.cpp
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "Windows/PropVariant.h"
|
|
||||||
|
|
||||||
#include "Common/ParseProperties.h"
|
|
||||||
|
|
||||||
#include "DeflateProps.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
|
|
||||||
static const UInt32 kAlgo1 = 0;
|
|
||||||
static const UInt32 kAlgo5 = 1;
|
|
||||||
|
|
||||||
static const UInt32 kPasses1 = 1;
|
|
||||||
static const UInt32 kPasses7 = 3;
|
|
||||||
static const UInt32 kPasses9 = 10;
|
|
||||||
|
|
||||||
static const UInt32 kFb1 = 32;
|
|
||||||
static const UInt32 kFb7 = 64;
|
|
||||||
static const UInt32 kFb9 = 128;
|
|
||||||
|
|
||||||
void CDeflateProps::Normalize()
|
|
||||||
{
|
|
||||||
UInt32 level = Level;
|
|
||||||
if (level == 0xFFFFFFFF)
|
|
||||||
level = 5;
|
|
||||||
|
|
||||||
if (Algo == 0xFFFFFFFF)
|
|
||||||
Algo = (level >= 5 ?
|
|
||||||
kAlgo5 :
|
|
||||||
kAlgo1);
|
|
||||||
|
|
||||||
if (NumPasses == 0xFFFFFFFF)
|
|
||||||
NumPasses =
|
|
||||||
(level >= 9 ? kPasses9 :
|
|
||||||
(level >= 7 ? kPasses7 :
|
|
||||||
kPasses1));
|
|
||||||
if (Fb == 0xFFFFFFFF)
|
|
||||||
Fb =
|
|
||||||
(level >= 9 ? kFb9 :
|
|
||||||
(level >= 7 ? kFb7 :
|
|
||||||
kFb1));
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CDeflateProps::SetCoderProperties(ICompressSetCoderProperties *setCoderProperties)
|
|
||||||
{
|
|
||||||
Normalize();
|
|
||||||
|
|
||||||
NWindows::NCOM::CPropVariant props[] =
|
|
||||||
{
|
|
||||||
Algo,
|
|
||||||
NumPasses,
|
|
||||||
Fb,
|
|
||||||
Mc
|
|
||||||
};
|
|
||||||
PROPID propIDs[] =
|
|
||||||
{
|
|
||||||
NCoderPropID::kAlgorithm,
|
|
||||||
NCoderPropID::kNumPasses,
|
|
||||||
NCoderPropID::kNumFastBytes,
|
|
||||||
NCoderPropID::kMatchFinderCycles
|
|
||||||
};
|
|
||||||
int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
|
|
||||||
if (!McDefined)
|
|
||||||
numProps--;
|
|
||||||
return setCoderProperties->SetCoderProperties(propIDs, props, numProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CDeflateProps::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
|
|
||||||
{
|
|
||||||
Init();
|
|
||||||
for (int i = 0; i < numProps; i++)
|
|
||||||
{
|
|
||||||
UString name = names[i];
|
|
||||||
name.MakeUpper();
|
|
||||||
if (name.IsEmpty())
|
|
||||||
return E_INVALIDARG;
|
|
||||||
const PROPVARIANT &prop = values[i];
|
|
||||||
if (name[0] == L'X')
|
|
||||||
{
|
|
||||||
UInt32 a = 9;
|
|
||||||
RINOK(ParsePropValue(name.Mid(1), prop, a));
|
|
||||||
Level = a;
|
|
||||||
}
|
|
||||||
else if (name.Left(1) == L"A")
|
|
||||||
{
|
|
||||||
UInt32 a = kAlgo5;
|
|
||||||
RINOK(ParsePropValue(name.Mid(1), prop, a));
|
|
||||||
Algo = a;
|
|
||||||
}
|
|
||||||
else if (name.Left(4) == L"PASS")
|
|
||||||
{
|
|
||||||
UInt32 a = kPasses9;
|
|
||||||
RINOK(ParsePropValue(name.Mid(4), prop, a));
|
|
||||||
NumPasses = a;
|
|
||||||
}
|
|
||||||
else if (name.Left(2) == L"FB")
|
|
||||||
{
|
|
||||||
UInt32 a = kFb9;
|
|
||||||
RINOK(ParsePropValue(name.Mid(2), prop, a));
|
|
||||||
Fb = a;
|
|
||||||
}
|
|
||||||
else if (name.Left(2) == L"MC")
|
|
||||||
{
|
|
||||||
UInt32 a = 0xFFFFFFFF;
|
|
||||||
RINOK(ParsePropValue(name.Mid(2), prop, a));
|
|
||||||
Mc = a;
|
|
||||||
McDefined = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,33 +3,4 @@
|
|||||||
#ifndef __DEFLATE_PROPS_H
|
#ifndef __DEFLATE_PROPS_H
|
||||||
#define __DEFLATE_PROPS_H
|
#define __DEFLATE_PROPS_H
|
||||||
|
|
||||||
#include "../ICoder.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
|
|
||||||
class CDeflateProps
|
|
||||||
{
|
|
||||||
UInt32 Level;
|
|
||||||
UInt32 NumPasses;
|
|
||||||
UInt32 Fb;
|
|
||||||
UInt32 Algo;
|
|
||||||
UInt32 Mc;
|
|
||||||
bool McDefined;
|
|
||||||
|
|
||||||
void Init()
|
|
||||||
{
|
|
||||||
Level = NumPasses = Fb = Algo = Mc = 0xFFFFFFFF;
|
|
||||||
McDefined = false;
|
|
||||||
}
|
|
||||||
void Normalize();
|
|
||||||
public:
|
|
||||||
CDeflateProps() { Init(); }
|
|
||||||
bool IsMaximum() const { return Algo > 0; }
|
|
||||||
|
|
||||||
HRESULT SetCoderProperties(ICompressSetCoderProperties *setCoderProperties);
|
|
||||||
HRESULT SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -277,9 +277,9 @@ static const CUInt32PCharPair g_AbiOS[] =
|
|||||||
|
|
||||||
static const CUInt32PCharPair g_SegmentFlags[] =
|
static const CUInt32PCharPair g_SegmentFlags[] =
|
||||||
{
|
{
|
||||||
{ 1 << 0, "Execute" },
|
{ 0, "Execute" },
|
||||||
{ 1 << 1, "Write" },
|
{ 1, "Write" },
|
||||||
{ 1 << 2, "Read" }
|
{ 2, "Read" }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *g_Types[] =
|
static const char *g_Types[] =
|
||||||
|
|||||||
@@ -526,7 +526,14 @@ HRESULT CDatabase::ReadDir(Int32 parent, UInt32 cluster, int level)
|
|||||||
item.Attrib = attrib;
|
item.Attrib = attrib;
|
||||||
item.Flags = p[12];
|
item.Flags = p[12];
|
||||||
item.Size = Get32(p + 28);
|
item.Size = Get32(p + 28);
|
||||||
item.Cluster = Get16(p + 26) | ((UInt32)Get16(p + 20) << 16);
|
item.Cluster = Get16(p + 26);
|
||||||
|
if (Header.NumFatBits > 16)
|
||||||
|
item.Cluster |= ((UInt32)Get16(p + 20) << 16);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// OS/2 and WinNT probably can store EA (extended atributes) in that field.
|
||||||
|
}
|
||||||
|
|
||||||
item.CTime = Get32(p + 14);
|
item.CTime = Get32(p + 14);
|
||||||
item.CTime2 = p[13];
|
item.CTime2 = p[13];
|
||||||
item.ADate = Get16(p + 18);
|
item.ADate = Get16(p + 18);
|
||||||
@@ -578,8 +585,12 @@ HRESULT CDatabase::Open()
|
|||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
UInt64 fileSize;
|
UInt64 fileSize;
|
||||||
RINOK(InStream->Seek(0, STREAM_SEEK_END, &fileSize));
|
RINOK(InStream->Seek(0, STREAM_SEEK_END, &fileSize));
|
||||||
|
|
||||||
|
/* we comment that check to support truncated images */
|
||||||
|
/*
|
||||||
if (fileSize < Header.GetPhySize())
|
if (fileSize < Header.GetPhySize())
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
*/
|
||||||
|
|
||||||
if (Header.IsFat32())
|
if (Header.IsFat32())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,11 +18,10 @@
|
|||||||
#include "../Compress/DeflateDecoder.h"
|
#include "../Compress/DeflateDecoder.h"
|
||||||
#include "../Compress/DeflateEncoder.h"
|
#include "../Compress/DeflateEncoder.h"
|
||||||
|
|
||||||
|
#include "Common/HandlerOut.h"
|
||||||
#include "Common/InStreamWithCRC.h"
|
#include "Common/InStreamWithCRC.h"
|
||||||
#include "Common/OutStreamWithCRC.h"
|
#include "Common/OutStreamWithCRC.h"
|
||||||
|
|
||||||
#include "DeflateProps.h"
|
|
||||||
|
|
||||||
#define Get32(p) GetUi32(p)
|
#define Get32(p) GetUi32(p)
|
||||||
|
|
||||||
using namespace NWindows;
|
using namespace NWindows;
|
||||||
@@ -305,7 +304,7 @@ class CHandler:
|
|||||||
CMyComPtr<ICompressCoder> _decoder;
|
CMyComPtr<ICompressCoder> _decoder;
|
||||||
NCompress::NDeflate::NDecoder::CCOMCoder *_decoderSpec;
|
NCompress::NDeflate::NDecoder::CCOMCoder *_decoderSpec;
|
||||||
|
|
||||||
CDeflateProps _method;
|
CSingleMethodProps _props;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties)
|
MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties)
|
||||||
@@ -321,7 +320,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
STATPROPSTG kProps[] =
|
static STATPROPSTG const kProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidPath, VT_BSTR},
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
{ NULL, kpidSize, VT_UI8},
|
{ NULL, kpidSize, VT_UI8},
|
||||||
@@ -545,7 +544,7 @@ static HRESULT UpdateArchive(
|
|||||||
ISequentialOutStream *outStream,
|
ISequentialOutStream *outStream,
|
||||||
UInt64 unpackSize,
|
UInt64 unpackSize,
|
||||||
const CItem &newItem,
|
const CItem &newItem,
|
||||||
CDeflateProps &deflateProps,
|
const CSingleMethodProps &props,
|
||||||
IArchiveUpdateCallback *updateCallback)
|
IArchiveUpdateCallback *updateCallback)
|
||||||
{
|
{
|
||||||
UInt64 complexity = 0;
|
UInt64 complexity = 0;
|
||||||
@@ -567,7 +566,7 @@ static HRESULT UpdateArchive(
|
|||||||
|
|
||||||
CItem item = newItem;
|
CItem item = newItem;
|
||||||
item.Method = NHeader::NCompressionMethod::kDeflate;
|
item.Method = NHeader::NCompressionMethod::kDeflate;
|
||||||
item.ExtraFlags = deflateProps.IsMaximum() ?
|
item.ExtraFlags = props.GetLevel() >= 7 ?
|
||||||
NHeader::NExtraFlags::kMaximum :
|
NHeader::NExtraFlags::kMaximum :
|
||||||
NHeader::NExtraFlags::kFastest;
|
NHeader::NExtraFlags::kFastest;
|
||||||
|
|
||||||
@@ -577,7 +576,7 @@ static HRESULT UpdateArchive(
|
|||||||
|
|
||||||
NCompress::NDeflate::NEncoder::CCOMCoder *deflateEncoderSpec = new NCompress::NDeflate::NEncoder::CCOMCoder;
|
NCompress::NDeflate::NEncoder::CCOMCoder *deflateEncoderSpec = new NCompress::NDeflate::NEncoder::CCOMCoder;
|
||||||
CMyComPtr<ICompressCoder> deflateEncoder = deflateEncoderSpec;
|
CMyComPtr<ICompressCoder> deflateEncoder = deflateEncoderSpec;
|
||||||
RINOK(deflateProps.SetCoderProperties(deflateEncoderSpec));
|
RINOK(props.SetCoderProps(deflateEncoderSpec, NULL));
|
||||||
RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, progress));
|
RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, progress));
|
||||||
|
|
||||||
item.Crc = inStreamSpec->GetCRC();
|
item.Crc = inStreamSpec->GetCRC();
|
||||||
@@ -616,8 +615,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
if (prop.vt != VT_FILETIME)
|
if (prop.vt != VT_FILETIME)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
utcTime = prop.filetime;
|
utcTime = prop.filetime;
|
||||||
if (!NTime::FileTimeToUnixTime(utcTime, newItem.Time))
|
NTime::FileTimeToUnixTime(utcTime, newItem.Time);
|
||||||
return E_INVALIDARG;
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
NCOM::CPropVariant prop;
|
NCOM::CPropVariant prop;
|
||||||
@@ -658,8 +656,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
size = prop.uhVal.QuadPart;
|
size = prop.uhVal.QuadPart;
|
||||||
}
|
}
|
||||||
|
return UpdateArchive(outStream, size, newItem, _props, updateCallback);
|
||||||
return UpdateArchive(outStream, size, newItem, _method, updateCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (indexInArchive != 0)
|
if (indexInArchive != 0)
|
||||||
@@ -680,7 +677,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
|
|
||||||
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
|
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
|
||||||
{
|
{
|
||||||
return _method.SetProperties(names, values, numProps);
|
return _props.SetProperties(names, values, numProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
static IInArchive *CreateArc() { return new CHandler; }
|
static IInArchive *CreateArc() { return new CHandler; }
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
BIN
CPP/7zip/Archive/Icons/squashfs.ico
Executable file
|
After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
@@ -3,9 +3,7 @@
|
|||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "Common/ComTry.h"
|
#include "Common/ComTry.h"
|
||||||
#include "Common/Defs.h"
|
|
||||||
#include "Common/IntToString.h"
|
#include "Common/IntToString.h"
|
||||||
#include "Common/NewHandler.h"
|
|
||||||
#include "Common/StringConvert.h"
|
#include "Common/StringConvert.h"
|
||||||
|
|
||||||
#include "Windows/PropVariant.h"
|
#include "Windows/PropVariant.h"
|
||||||
@@ -26,7 +24,7 @@ using namespace NTime;
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NIso {
|
namespace NIso {
|
||||||
|
|
||||||
STATPROPSTG kProps[] =
|
static const STATPROPSTG kProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidPath, VT_BSTR},
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
{ NULL, kpidIsDir, VT_BOOL},
|
{ NULL, kpidIsDir, VT_BOOL},
|
||||||
@@ -35,8 +33,17 @@ STATPROPSTG kProps[] =
|
|||||||
{ NULL, kpidMTime, VT_FILETIME}
|
{ NULL, kpidMTime, VT_FILETIME}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const STATPROPSTG kArcProps[] =
|
||||||
|
{
|
||||||
|
{ NULL, kpidComment, VT_BSTR},
|
||||||
|
{ NULL, kpidCTime, VT_FILETIME},
|
||||||
|
{ NULL, kpidMTime, VT_FILETIME}
|
||||||
|
// { NULL, kpidPhySize, VT_UI8},
|
||||||
|
// { NULL, kpidHeadersSize, VT_UI8}
|
||||||
|
};
|
||||||
|
|
||||||
IMP_IInArchive_Props
|
IMP_IInArchive_Props
|
||||||
IMP_IInArchive_ArcProps_NO
|
IMP_IInArchive_ArcProps
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||||
const UInt64 * /* maxCheckStartPosition */,
|
const UInt64 * /* maxCheckStartPosition */,
|
||||||
@@ -68,6 +75,58 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void AddString(AString &s, const char *name, const Byte *p, int size)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < size && p[i]; i++);
|
||||||
|
for (; i > 0 && p[i - 1] == ' '; i--);
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
AString d;
|
||||||
|
memcpy(d.GetBuffer(i), p, i);
|
||||||
|
d.ReleaseBuffer(i);
|
||||||
|
s += '\n';
|
||||||
|
s += name;
|
||||||
|
s += ": ";
|
||||||
|
s += d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ADD_STRING(n, v) AddString(s, n, vol. ## v, sizeof(vol. ## v))
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
NWindows::NCOM::CPropVariant prop;
|
||||||
|
const CVolumeDescriptor &vol = _archive.VolDescs[_archive.MainVolDescIndex];
|
||||||
|
switch(propID)
|
||||||
|
{
|
||||||
|
case kpidComment:
|
||||||
|
{
|
||||||
|
AString s;
|
||||||
|
ADD_STRING("System", SystemId);
|
||||||
|
ADD_STRING("Volume", VolumeId);
|
||||||
|
ADD_STRING("VolumeSet", VolumeSetId);
|
||||||
|
ADD_STRING("Publisher", PublisherId);
|
||||||
|
ADD_STRING("Preparer", DataPreparerId);
|
||||||
|
ADD_STRING("Application", ApplicationId);
|
||||||
|
ADD_STRING("Copyright", CopyrightFileId);
|
||||||
|
ADD_STRING("Abstract", AbstractFileId);
|
||||||
|
ADD_STRING("Bib", BibFileId);
|
||||||
|
prop = s;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kpidCTime: { FILETIME utc; if (vol.CTime.GetFileTime(utc)) prop = utc; break; }
|
||||||
|
case kpidMTime: { FILETIME utc; if (vol.MTime.GetFileTime(utc)) prop = utc; break; }
|
||||||
|
// case kpidPhySize: break;
|
||||||
|
// case kpidHeadersSize: break;
|
||||||
|
case kpidError: if (_archive.IncorrectBigEndian) prop = "Incorrect big-endian headers"; break;
|
||||||
|
}
|
||||||
|
prop.Detach(value);
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
@@ -89,9 +148,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
prop = (const wchar_t *)s;
|
prop = (const wchar_t *)s;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kpidIsDir:
|
case kpidIsDir: prop = false; break;
|
||||||
prop = false;
|
|
||||||
break;
|
|
||||||
case kpidSize:
|
case kpidSize:
|
||||||
case kpidPackSize:
|
case kpidPackSize:
|
||||||
prop = (UInt64)_archive.GetBootItemSize(index);
|
prop = (UInt64)_archive.GetBootItemSize(index);
|
||||||
@@ -115,17 +172,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
|
|
||||||
int pos = s.ReverseFind(L';');
|
int pos = s.ReverseFind(L';');
|
||||||
if (pos >= 0 && pos == s.Length() - 2)
|
if (pos >= 0 && pos == s.Length() - 2)
|
||||||
if (s[s.Length() - 1] == L'1')
|
if (s.Back() == L'1')
|
||||||
s = s.Left(pos);
|
s = s.Left(pos);
|
||||||
if (!s.IsEmpty())
|
if (!s.IsEmpty())
|
||||||
if (s[s.Length() - 1] == L'.')
|
if (s.Back() == L'.')
|
||||||
s = s.Left(s.Length() - 1);
|
s.DeleteBack();
|
||||||
prop = (const wchar_t *)NItemName::GetOSName2(s);
|
prop = (const wchar_t *)NItemName::GetOSName2(s);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kpidIsDir:
|
case kpidIsDir: prop = item.IsDir(); break;
|
||||||
prop = item.IsDir();
|
|
||||||
break;
|
|
||||||
case kpidSize:
|
case kpidSize:
|
||||||
case kpidPackSize:
|
case kpidPackSize:
|
||||||
if (!item.IsDir())
|
if (!item.IsDir())
|
||||||
@@ -133,16 +188,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
break;
|
break;
|
||||||
case kpidMTime:
|
case kpidMTime:
|
||||||
{
|
{
|
||||||
FILETIME utcFileTime;
|
FILETIME utc;
|
||||||
if (item.DateTime.GetFileTime(utcFileTime))
|
if (item.DateTime.GetFileTime(utc))
|
||||||
prop = utcFileTime;
|
prop = utc;
|
||||||
/*
|
|
||||||
else
|
|
||||||
{
|
|
||||||
utcFileTime.dwLowDateTime = 0;
|
|
||||||
utcFileTime.dwHighDateTime = 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,19 +211,18 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
UInt64 totalSize = 0;
|
UInt64 totalSize = 0;
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
for(i = 0; i < numItems; i++)
|
for (i = 0; i < numItems; i++)
|
||||||
{
|
{
|
||||||
UInt32 index = (allFilesMode ? i : indices[i]);
|
UInt32 index = (allFilesMode ? i : indices[i]);
|
||||||
if (index < (UInt32)_archive.Refs.Size())
|
if (index < (UInt32)_archive.Refs.Size())
|
||||||
{
|
{
|
||||||
const CRef &ref = _archive.Refs[index];
|
const CRef &ref = _archive.Refs[index];
|
||||||
const CDir &item = ref.Dir->_subItems[ref.Index];
|
const CDir &item = ref.Dir->_subItems[ref.Index];
|
||||||
totalSize += item.DataLength;
|
if (!item.IsDir())
|
||||||
|
totalSize += item.DataLength;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
totalSize += _archive.GetBootItemSize(index - _archive.Refs.Size());
|
totalSize += _archive.GetBootItemSize(index - _archive.Refs.Size());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
extractCallback->SetTotal(totalSize);
|
extractCallback->SetTotal(totalSize);
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ UInt16 CInArchive::ReadUInt16()
|
|||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
if (b[i] != b[3 - i])
|
if (b[i] != b[3 - i])
|
||||||
throw 1;
|
IncorrectBigEndian = true;
|
||||||
value |= ((UInt16)(b[i]) << (8 * i));
|
value |= ((UInt16)(b[i]) << (8 * i));
|
||||||
}
|
}
|
||||||
return (UInt16)value;
|
return (UInt16)value;
|
||||||
@@ -440,6 +440,7 @@ HRESULT CInArchive::Open(IInStream *inStream)
|
|||||||
|
|
||||||
void CInArchive::Clear()
|
void CInArchive::Clear()
|
||||||
{
|
{
|
||||||
|
IncorrectBigEndian = false;
|
||||||
Refs.Clear();
|
Refs.Clear();
|
||||||
_rootDir.Clear();
|
_rootDir.Clear();
|
||||||
VolDescs.Clear();
|
VolDescs.Clear();
|
||||||
|
|||||||
@@ -111,6 +111,20 @@ struct CDateTime
|
|||||||
signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded.
|
signed char GmtOffset; // min intervals from -48 (West) to +52 (East) recorded.
|
||||||
bool NotSpecified() const { return Year == 0 && Month == 0 && Day == 0 &&
|
bool NotSpecified() const { return Year == 0 && Month == 0 && Day == 0 &&
|
||||||
Hour == 0 && Minute == 0 && Second == 0 && GmtOffset == 0; }
|
Hour == 0 && Minute == 0 && Second == 0 && GmtOffset == 0; }
|
||||||
|
|
||||||
|
bool GetFileTime(FILETIME &ft) const
|
||||||
|
{
|
||||||
|
UInt64 value;
|
||||||
|
bool res = NWindows::NTime::GetSecondsSince1601(Year, Month, Day, Hour, Minute, Second, value);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
value -= (UInt64)((Int64)GmtOffset * 15 * 60);
|
||||||
|
value *= 10000000;
|
||||||
|
}
|
||||||
|
ft.dwLowDateTime = (DWORD)value;
|
||||||
|
ft.dwHighDateTime = (DWORD)(value >> 32);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CBootRecordDescriptor
|
struct CBootRecordDescriptor
|
||||||
@@ -268,6 +282,7 @@ public:
|
|||||||
int MainVolDescIndex;
|
int MainVolDescIndex;
|
||||||
UInt32 BlockSize;
|
UInt32 BlockSize;
|
||||||
CObjectVector<CBootInitialEntry> BootEntries;
|
CObjectVector<CBootInitialEntry> BootEntries;
|
||||||
|
bool IncorrectBigEndian;
|
||||||
|
|
||||||
|
|
||||||
bool IsJoliet() const { return VolDescs[MainVolDescIndex].IsJoliet(); }
|
bool IsJoliet() const { return VolDescs[MainVolDescIndex].IsJoliet(); }
|
||||||
|
|||||||
@@ -8,6 +8,6 @@
|
|||||||
static IInArchive *CreateArc() { return new NArchive::NIso::CHandler; }
|
static IInArchive *CreateArc() { return new NArchive::NIso::CHandler; }
|
||||||
|
|
||||||
static CArcInfo g_ArcInfo =
|
static CArcInfo g_ArcInfo =
|
||||||
{ L"Iso", L"iso", 0, 0xE7, { 'C', 'D', '0', '0', '1', 0x1 }, 7, false, CreateArc, 0 };
|
{ L"Iso", L"iso img", 0, 0xE7, { 'C', 'D', '0', '0', '1', 0x1 }, 7, false, CreateArc, 0 };
|
||||||
|
|
||||||
REGISTER_ARC(Iso)
|
REGISTER_ARC(Iso)
|
||||||
|
|||||||