mirror of
https://github.com/Xevion/easy7zip.git
synced 2026-01-31 04:24:11 -06:00
4.59 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
3901bf0ab8
commit
173c07e166
@@ -7,7 +7,7 @@ CRC1b macro
|
|||||||
movzx EDX, BYTE PTR [RSI]
|
movzx EDX, BYTE PTR [RSI]
|
||||||
inc RSI
|
inc RSI
|
||||||
movzx EBX, AL
|
movzx EBX, AL
|
||||||
xor EDX, EBX
|
xor EDX, EBX
|
||||||
shr EAX, 8
|
shr EAX, 8
|
||||||
xor EAX, [RDI + RDX * 4]
|
xor EAX, [RDI + RDX * 4]
|
||||||
dec R8
|
dec R8
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ CRC1b macro
|
|||||||
movzx EDX, BYTE PTR [ESI]
|
movzx EDX, BYTE PTR [ESI]
|
||||||
inc ESI
|
inc ESI
|
||||||
movzx EBX, AL
|
movzx EBX, AL
|
||||||
xor EDX, EBX
|
xor EDX, EBX
|
||||||
shr EAX, 8
|
shr EAX, 8
|
||||||
xor EAX, [EBP + EDX * 4]
|
xor EAX, [EBP + EDX * 4]
|
||||||
dec EDI
|
dec EDI
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* 7zCrc.c -- CRC32 calculation
|
/* 7zCrc.c -- CRC32 calculation
|
||||||
2008-03-13
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ void MY_FAST_CALL CrcGenerateTable(void)
|
|||||||
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)
|
||||||
{
|
{
|
||||||
const Byte *p = (const Byte *)data;
|
const Byte *p = (const Byte *)data;
|
||||||
for (; size > 0 ; size--, p++)
|
for (; size > 0 ; size--, p++)
|
||||||
v = CRC_UPDATE_BYTE(v, *p);
|
v = CRC_UPDATE_BYTE(v, *p);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Aes.c -- AES encryption / decryption
|
/* Aes.c -- AES encryption / decryption
|
||||||
2008-03-26
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@ Public domain */
|
|||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
|
||||||
static UInt32 T[256 * 4];
|
static UInt32 T[256 * 4];
|
||||||
static Byte Sbox[256] = {
|
static Byte Sbox[256] = {
|
||||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||||
@@ -114,16 +114,16 @@ void Aes_SetKeyEncode(CAes *p, const Byte *key, unsigned keySize)
|
|||||||
wSize = (p->numRounds2 * 2 + 1) * 4;
|
wSize = (p->numRounds2 * 2 + 1) * 4;
|
||||||
w = p->rkey;
|
w = p->rkey;
|
||||||
|
|
||||||
for (i = 0; i < keySize; i++, key += 4)
|
for (i = 0; i < keySize; i++, key += 4)
|
||||||
w[i] = Ui32(key[0], key[1], key[2], key[3]);
|
w[i] = Ui32(key[0], key[1], key[2], key[3]);
|
||||||
|
|
||||||
for (; i < wSize; i++)
|
for (; i < wSize; i++)
|
||||||
{
|
{
|
||||||
UInt32 t = w[i - 1];
|
UInt32 t = w[i - 1];
|
||||||
unsigned rem = i % keySize;
|
unsigned rem = i % keySize;
|
||||||
if (rem == 0)
|
if (rem == 0)
|
||||||
t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]);
|
t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]);
|
||||||
else if (keySize > 6 && rem == 4)
|
else if (keySize > 6 && rem == 4)
|
||||||
t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]);
|
t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]);
|
||||||
w[i] = w[i - keySize] ^ t;
|
w[i] = w[i - keySize] ^ t;
|
||||||
}
|
}
|
||||||
@@ -139,7 +139,7 @@ void Aes_SetKeyDecode(CAes *p, const Byte *key, unsigned keySize)
|
|||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
UInt32 r = w[i];
|
UInt32 r = w[i];
|
||||||
w[i] =
|
w[i] =
|
||||||
D[ Sbox[gb0(r)]] ^
|
D[ Sbox[gb0(r)]] ^
|
||||||
D[0x100 + Sbox[gb1(r)]] ^
|
D[0x100 + Sbox[gb1(r)]] ^
|
||||||
D[0x200 + Sbox[gb2(r)]] ^
|
D[0x200 + Sbox[gb2(r)]] ^
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Aes.h -- AES encryption / decryption
|
/* Aes.h -- AES encryption / decryption
|
||||||
2008-03-26
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ typedef struct
|
|||||||
void AesGenTables(void);
|
void AesGenTables(void);
|
||||||
|
|
||||||
/* keySize = 16 or 24 or 32 (bytes) */
|
/* keySize = 16 or 24 or 32 (bytes) */
|
||||||
void Aes_SetKeyEncode(CAes *p, const Byte *key, unsigned keySize);
|
void Aes_SetKeyEncode(CAes *p, const Byte *key, unsigned keySize);
|
||||||
void Aes_SetKeyDecode(CAes *p, const Byte *key, unsigned keySize);
|
void Aes_SetKeyDecode(CAes *p, const Byte *key, unsigned keySize);
|
||||||
|
|
||||||
/* Aes_Encode32 and Aes_Decode32 functions work with little-endian words.
|
/* Aes_Encode32 and Aes_Decode32 functions work with little-endian words.
|
||||||
@@ -39,8 +39,8 @@ void AesCbc_Init(CAesCbc *p, const Byte *iv); /* iv size is AES_BLOCK_SIZE */
|
|||||||
|
|
||||||
/* AesCbc_Encode and AesCbc_Decode:
|
/* AesCbc_Encode and AesCbc_Decode:
|
||||||
if (res <= size): Filter have converted res bytes
|
if (res <= size): Filter have converted res bytes
|
||||||
if (res > size): Filter have not converted anything. And it needs at
|
if (res > size): Filter have not converted anything. And it needs at
|
||||||
least res = AES_BLOCK_SIZE bytes to convert one block */
|
least res = AES_BLOCK_SIZE bytes to convert one block */
|
||||||
|
|
||||||
SizeT AesCbc_Encode(CAesCbc *p, Byte *data, SizeT size);
|
SizeT AesCbc_Encode(CAesCbc *p, Byte *data, SizeT size);
|
||||||
SizeT AesCbc_Decode(CAesCbc *p, Byte *data, SizeT size);
|
SizeT AesCbc_Decode(CAesCbc *p, Byte *data, SizeT size);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Alloc.c -- Memory allocation functions
|
/* Alloc.c -- Memory allocation functions
|
||||||
2008-03-13
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ void *BigAlloc(size_t size)
|
|||||||
#ifdef _7ZIP_LARGE_PAGES
|
#ifdef _7ZIP_LARGE_PAGES
|
||||||
if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
|
if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
|
||||||
{
|
{
|
||||||
void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
|
void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
|
||||||
MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
|
MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
+12
-12
@@ -1,5 +1,5 @@
|
|||||||
/* 7zDecode.c Decoding from 7z folder
|
/* 7zDecode.c Decoding from 7z folder
|
||||||
2008-04-09
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read 7zDecode.h for license options */
|
Read 7zDecode.h for license options */
|
||||||
@@ -60,13 +60,13 @@ static SRes SzDecodeLzma(CSzCoderInfo *coder, CFileSize inSize, ISzInStream *inS
|
|||||||
if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
|
if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
|
||||||
{
|
{
|
||||||
if (state.dicBufSize != outSize || _inSize != 0 ||
|
if (state.dicBufSize != outSize || _inSize != 0 ||
|
||||||
(status != LZMA_STATUS_FINISHED_WITH_MARK &&
|
(status != LZMA_STATUS_FINISHED_WITH_MARK &&
|
||||||
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
|
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
|
||||||
res = SZ_ERROR_DATA;
|
res = SZ_ERROR_DATA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LzmaDec_FreeProbs(&state, allocMain);
|
LzmaDec_FreeProbs(&state, allocMain);
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ SRes CheckSupportedFolder(const CSzFolder *f)
|
|||||||
IS_UNSUPPORTED_CODER(f->Coders[2]) ||
|
IS_UNSUPPORTED_CODER(f->Coders[2]) ||
|
||||||
IS_NO_BCJ2(f->Coders[3]))
|
IS_NO_BCJ2(f->Coders[3]))
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
if (f->NumPackStreams != 4 ||
|
if (f->NumPackStreams != 4 ||
|
||||||
f->PackStreams[0] != 2 ||
|
f->PackStreams[0] != 2 ||
|
||||||
f->PackStreams[1] != 6 ||
|
f->PackStreams[1] != 6 ||
|
||||||
f->PackStreams[2] != 1 ||
|
f->PackStreams[2] != 1 ||
|
||||||
@@ -184,7 +184,7 @@ SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder,
|
|||||||
if (folder->NumCoders == 4)
|
if (folder->NumCoders == 4)
|
||||||
{
|
{
|
||||||
UInt32 indices[] = { 3, 2, 0 };
|
UInt32 indices[] = { 3, 2, 0 };
|
||||||
CFileSize unpackSize = folder->UnPackSizes[ci];
|
CFileSize unpackSize = folder->UnpackSizes[ci];
|
||||||
si = indices[ci];
|
si = indices[ci];
|
||||||
if (ci < 2)
|
if (ci < 2)
|
||||||
{
|
{
|
||||||
@@ -287,22 +287,22 @@ SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
res = Bcj2_Decode(
|
res = Bcj2_Decode(
|
||||||
tempBuf3, tempSize3,
|
tempBuf3, tempSize3,
|
||||||
tempBuf[0], tempSizes[0],
|
tempBuf[0], tempSizes[0],
|
||||||
tempBuf[1], tempSizes[1],
|
tempBuf[1], tempSizes[1],
|
||||||
/*
|
/*
|
||||||
#ifdef _LZMA_IN_CB
|
#ifdef _LZMA_IN_CB
|
||||||
*/
|
*/
|
||||||
tempBuf[2], tempSizes[2],
|
tempBuf[2], tempSizes[2],
|
||||||
/*
|
/*
|
||||||
#else
|
#else
|
||||||
inBuffer + (size_t)offset, (size_t)s3Size,
|
inBuffer + (size_t)offset, (size_t)s3Size,
|
||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
outBuffer, outSize);
|
outBuffer, outSize);
|
||||||
RINOK(res)
|
RINOK(res)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
|
|||||||
+19
-19
@@ -1,5 +1,5 @@
|
|||||||
/* 7zExtract.c -- Extracting from 7z archive
|
/* 7zExtract.c -- Extracting from 7z archive
|
||||||
2008-04-09
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read 7zExtract.h for license options */
|
Read 7zExtract.h for license options */
|
||||||
@@ -10,13 +10,13 @@ Read 7zExtract.h for license options */
|
|||||||
|
|
||||||
SRes SzAr_Extract(
|
SRes SzAr_Extract(
|
||||||
const CSzArEx *p,
|
const CSzArEx *p,
|
||||||
ISzInStream *inStream,
|
ISzInStream *inStream,
|
||||||
UInt32 fileIndex,
|
UInt32 fileIndex,
|
||||||
UInt32 *blockIndex,
|
UInt32 *blockIndex,
|
||||||
Byte **outBuffer,
|
Byte **outBuffer,
|
||||||
size_t *outBufferSize,
|
size_t *outBufferSize,
|
||||||
size_t *offset,
|
size_t *offset,
|
||||||
size_t *outSizeProcessed,
|
size_t *outSizeProcessed,
|
||||||
ISzAlloc *allocMain,
|
ISzAlloc *allocMain,
|
||||||
ISzAlloc *allocTemp)
|
ISzAlloc *allocTemp)
|
||||||
{
|
{
|
||||||
@@ -36,11 +36,11 @@ SRes SzAr_Extract(
|
|||||||
if (*outBuffer == 0 || *blockIndex != folderIndex)
|
if (*outBuffer == 0 || *blockIndex != folderIndex)
|
||||||
{
|
{
|
||||||
CSzFolder *folder = p->db.Folders + folderIndex;
|
CSzFolder *folder = p->db.Folders + folderIndex;
|
||||||
CFileSize unPackSizeSpec = SzFolder_GetUnPackSize(folder);
|
CFileSize unpackSizeSpec = SzFolder_GetUnpackSize(folder);
|
||||||
size_t unPackSize = (size_t)unPackSizeSpec;
|
size_t unpackSize = (size_t)unpackSizeSpec;
|
||||||
CFileSize startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);
|
CFileSize startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);
|
||||||
|
|
||||||
if (unPackSize != unPackSizeSpec)
|
if (unpackSize != unpackSizeSpec)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
*blockIndex = folderIndex;
|
*blockIndex = folderIndex;
|
||||||
IAlloc_Free(allocMain, *outBuffer);
|
IAlloc_Free(allocMain, *outBuffer);
|
||||||
@@ -50,24 +50,24 @@ SRes SzAr_Extract(
|
|||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
*outBufferSize = unPackSize;
|
*outBufferSize = unpackSize;
|
||||||
if (unPackSize != 0)
|
if (unpackSize != 0)
|
||||||
{
|
{
|
||||||
*outBuffer = (Byte *)IAlloc_Alloc(allocMain, unPackSize);
|
*outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
|
||||||
if (*outBuffer == 0)
|
if (*outBuffer == 0)
|
||||||
res = SZ_ERROR_MEM;
|
res = SZ_ERROR_MEM;
|
||||||
}
|
}
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
res = SzDecode(p->db.PackSizes +
|
res = SzDecode(p->db.PackSizes +
|
||||||
p->FolderStartPackStreamIndex[folderIndex], folder,
|
p->FolderStartPackStreamIndex[folderIndex], folder,
|
||||||
inStream, startOffset,
|
inStream, startOffset,
|
||||||
*outBuffer, unPackSize, allocTemp);
|
*outBuffer, unpackSize, allocTemp);
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
if (folder->UnPackCRCDefined)
|
if (folder->UnpackCRCDefined)
|
||||||
{
|
{
|
||||||
if (CrcCalc(*outBuffer, unPackSize) != folder->UnPackCRC)
|
if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)
|
||||||
res = SZ_ERROR_CRC;
|
res = SZ_ERROR_CRC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ SRes SzAr_Extract(
|
|||||||
}
|
}
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
CSzFileItem *fileItem = p->db.Files + fileIndex;
|
CSzFileItem *fileItem = p->db.Files + fileIndex;
|
||||||
*offset = 0;
|
*offset = 0;
|
||||||
for(i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
for(i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
||||||
@@ -85,7 +85,7 @@ SRes SzAr_Extract(
|
|||||||
if (*offset + *outSizeProcessed > *outBufferSize)
|
if (*offset + *outSizeProcessed > *outBufferSize)
|
||||||
return SZ_ERROR_FAIL;
|
return SZ_ERROR_FAIL;
|
||||||
{
|
{
|
||||||
if (fileItem->IsFileCRCDefined)
|
if (fileItem->FileCRCDefined)
|
||||||
{
|
{
|
||||||
if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)
|
if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)
|
||||||
res = SZ_ERROR_CRC;
|
res = SZ_ERROR_CRC;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* 7zExtract.h -- Extracting from 7z archive
|
/* 7zExtract.h -- Extracting from 7z archive
|
||||||
2008-04-09
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read 7zItem.h for license options */
|
Read 7zItem.h for license options */
|
||||||
@@ -12,18 +12,18 @@ Read 7zItem.h for license options */
|
|||||||
/*
|
/*
|
||||||
SzExtract extracts file from archive
|
SzExtract extracts file from archive
|
||||||
|
|
||||||
*outBuffer must be 0 before first call for each new archive.
|
*outBuffer must be 0 before first call for each new archive.
|
||||||
|
|
||||||
Extracting cache:
|
Extracting cache:
|
||||||
If you need to decompress more than one file, you can send
|
If you need to decompress more than one file, you can send
|
||||||
these values from previous call:
|
these values from previous call:
|
||||||
*blockIndex,
|
*blockIndex,
|
||||||
*outBuffer,
|
*outBuffer,
|
||||||
*outBufferSize
|
*outBufferSize
|
||||||
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
||||||
it will increase decompression speed.
|
it will increase decompression speed.
|
||||||
|
|
||||||
If you use external function, you can declare these 3 cache variables
|
If you use external function, you can declare these 3 cache variables
|
||||||
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
||||||
|
|
||||||
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
||||||
@@ -31,7 +31,7 @@ Read 7zItem.h for license options */
|
|||||||
|
|
||||||
SRes SzAr_Extract(
|
SRes SzAr_Extract(
|
||||||
const CSzArEx *db,
|
const CSzArEx *db,
|
||||||
ISzInStream *inStream,
|
ISzInStream *inStream,
|
||||||
UInt32 fileIndex, /* index of file */
|
UInt32 fileIndex, /* index of file */
|
||||||
UInt32 *blockIndex, /* index of solid block */
|
UInt32 *blockIndex, /* index of solid block */
|
||||||
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* 7zHeader.h -- 7z Headers
|
/* 7zHeader.h -- 7z Headers
|
||||||
2008-03-17
|
2008-07-14
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read LzmaDec.h for license options */
|
Read LzmaDec.h for license options */
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ enum EIdEnum
|
|||||||
k7zIdFilesInfo,
|
k7zIdFilesInfo,
|
||||||
|
|
||||||
k7zIdPackInfo,
|
k7zIdPackInfo,
|
||||||
k7zIdUnPackInfo,
|
k7zIdUnpackInfo,
|
||||||
k7zIdSubStreamsInfo,
|
k7zIdSubStreamsInfo,
|
||||||
|
|
||||||
k7zIdSize,
|
k7zIdSize,
|
||||||
@@ -36,23 +36,24 @@ enum EIdEnum
|
|||||||
|
|
||||||
k7zIdFolder,
|
k7zIdFolder,
|
||||||
|
|
||||||
k7zIdCodersUnPackSize,
|
k7zIdCodersUnpackSize,
|
||||||
k7zIdNumUnPackStream,
|
k7zIdNumUnpackStream,
|
||||||
|
|
||||||
k7zIdEmptyStream,
|
k7zIdEmptyStream,
|
||||||
k7zIdEmptyFile,
|
k7zIdEmptyFile,
|
||||||
k7zIdAnti,
|
k7zIdAnti,
|
||||||
|
|
||||||
k7zIdName,
|
k7zIdName,
|
||||||
k7zIdCreationTime,
|
k7zIdCTime,
|
||||||
k7zIdLastAccessTime,
|
k7zIdATime,
|
||||||
k7zIdLastWriteTime,
|
k7zIdMTime,
|
||||||
k7zIdWinAttributes,
|
k7zIdWinAttributes,
|
||||||
k7zIdComment,
|
k7zIdComment,
|
||||||
|
|
||||||
k7zIdEncodedHeader,
|
k7zIdEncodedHeader,
|
||||||
|
|
||||||
k7zIdStartPos
|
k7zIdStartPos,
|
||||||
|
k7zIdDummy
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+107
-119
@@ -1,5 +1,5 @@
|
|||||||
/* 7zIn.c -- 7z Input functions
|
/* 7zIn.c -- 7z Input functions
|
||||||
2008-04-09
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read 7zIn.h for license options */
|
Read 7zIn.h for license options */
|
||||||
@@ -30,7 +30,7 @@ void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
CFileSize GetFolderPackStreamSize(int folderIndex, int streamIndex) const
|
CFileSize GetFolderPackStreamSize(int folderIndex, int streamIndex) const
|
||||||
{
|
{
|
||||||
return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
|
return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
|
||||||
}
|
}
|
||||||
@@ -96,7 +96,7 @@ static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
|
|||||||
if (folderIndex >= p->db.NumFolders)
|
if (folderIndex >= p->db.NumFolders)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
p->FolderStartFileIndex[folderIndex] = i;
|
p->FolderStartFileIndex[folderIndex] = i;
|
||||||
if (p->db.Folders[folderIndex].NumUnPackStreams != 0)
|
if (p->db.Folders[folderIndex].NumUnpackStreams != 0)
|
||||||
break;
|
break;
|
||||||
folderIndex++;
|
folderIndex++;
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
|
|||||||
if (emptyStream)
|
if (emptyStream)
|
||||||
continue;
|
continue;
|
||||||
indexInFolder++;
|
indexInFolder++;
|
||||||
if (indexInFolder >= p->db.Folders[folderIndex].NumUnPackStreams)
|
if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams)
|
||||||
{
|
{
|
||||||
folderIndex++;
|
folderIndex++;
|
||||||
indexInFolder = 0;
|
indexInFolder = 0;
|
||||||
@@ -117,7 +117,7 @@ static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
|
|||||||
|
|
||||||
CFileSize SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder)
|
CFileSize SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder)
|
||||||
{
|
{
|
||||||
return p->ArchiveInfo.DataStartPosition +
|
return p->ArchiveInfo.DataStartPosition +
|
||||||
p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
|
p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,21 +164,9 @@ SRes SzReadTime(const CObjectVector<CBuf> &dataVector,
|
|||||||
}
|
}
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case k7zIdCreationTime:
|
case k7zIdCTime: file.IsCTimeDefined = defined; if (defined) file.CTime = fileTime; break;
|
||||||
file.IsCreationTimeDefined = defined;
|
case k7zIdATime: file.IsATimeDefined = defined; if (defined) file.ATime = fileTime; break;
|
||||||
if (defined)
|
case k7zIdMTime: file.IsMTimeDefined = defined; if (defined) file.MTime = fileTime; break;
|
||||||
file.CreationTime = fileTime;
|
|
||||||
break;
|
|
||||||
case k7zIdLastWriteTime:
|
|
||||||
file.IsLastWriteTimeDefined = defined;
|
|
||||||
if (defined)
|
|
||||||
file.LastWriteTime = fileTime;
|
|
||||||
break;
|
|
||||||
case k7zIdLastAccessTime:
|
|
||||||
file.IsLastAccessTimeDefined = defined;
|
|
||||||
if (defined)
|
|
||||||
file.LastAccessTime = fileTime;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
@@ -327,9 +315,9 @@ static SRes SzReadNumber32(CSzData *sd, UInt32 *value)
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes SzReadID(CSzData *sd, UInt64 *value)
|
static SRes SzReadID(CSzData *sd, UInt64 *value)
|
||||||
{
|
{
|
||||||
return SzReadNumber(sd, value);
|
return SzReadNumber(sd, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes SzSkeepDataSize(CSzData *sd, UInt64 size)
|
static SRes SzSkeepDataSize(CSzData *sd, UInt64 size)
|
||||||
@@ -408,10 +396,10 @@ static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, ISzAlloc *
|
|||||||
}
|
}
|
||||||
|
|
||||||
static SRes SzReadHashDigests(
|
static SRes SzReadHashDigests(
|
||||||
CSzData *sd,
|
CSzData *sd,
|
||||||
size_t numItems,
|
size_t numItems,
|
||||||
Byte **digestsDefined,
|
Byte **digestsDefined,
|
||||||
UInt32 **digests,
|
UInt32 **digests,
|
||||||
ISzAlloc *alloc)
|
ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
@@ -426,7 +414,7 @@ static SRes SzReadHashDigests(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static SRes SzReadPackInfo(
|
static SRes SzReadPackInfo(
|
||||||
CSzData *sd,
|
CSzData *sd,
|
||||||
CFileSize *dataOffset,
|
CFileSize *dataOffset,
|
||||||
UInt32 *numPackStreams,
|
UInt32 *numPackStreams,
|
||||||
CFileSize **packSizes,
|
CFileSize **packSizes,
|
||||||
@@ -455,7 +443,7 @@ static SRes SzReadPackInfo(
|
|||||||
break;
|
break;
|
||||||
if (type == k7zIdCRC)
|
if (type == k7zIdCRC)
|
||||||
{
|
{
|
||||||
RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc));
|
RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RINOK(SzSkeepData(sd));
|
RINOK(SzSkeepData(sd));
|
||||||
@@ -562,7 +550,7 @@ static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
|
|||||||
{
|
{
|
||||||
CBindPair *bindPair = folder->BindPairs + i;;
|
CBindPair *bindPair = folder->BindPairs + i;;
|
||||||
RINOK(SzReadNumber32(sd, &bindPair->InIndex));
|
RINOK(SzReadNumber32(sd, &bindPair->InIndex));
|
||||||
RINOK(SzReadNumber32(sd, &bindPair->OutIndex));
|
RINOK(SzReadNumber32(sd, &bindPair->OutIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
numPackedStreams = numInStreams - (UInt32)numBindPairs;
|
numPackedStreams = numInStreams - (UInt32)numBindPairs;
|
||||||
@@ -589,8 +577,8 @@ static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes SzReadUnPackInfo(
|
static SRes SzReadUnpackInfo(
|
||||||
CSzData *sd,
|
CSzData *sd,
|
||||||
UInt32 *numFolders,
|
UInt32 *numFolders,
|
||||||
CSzFolder **folders, /* for alloc */
|
CSzFolder **folders, /* for alloc */
|
||||||
ISzAlloc *alloc,
|
ISzAlloc *alloc,
|
||||||
@@ -613,7 +601,7 @@ static SRes SzReadUnPackInfo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RINOK(SzWaitAttribute(sd, k7zIdCodersUnPackSize));
|
RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize));
|
||||||
|
|
||||||
for (i = 0; i < *numFolders; i++)
|
for (i = 0; i < *numFolders; i++)
|
||||||
{
|
{
|
||||||
@@ -621,11 +609,11 @@ static SRes SzReadUnPackInfo(
|
|||||||
CSzFolder *folder = (*folders) + i;
|
CSzFolder *folder = (*folders) + i;
|
||||||
UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder);
|
UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder);
|
||||||
|
|
||||||
MY_ALLOC(CFileSize, folder->UnPackSizes, (size_t)numOutStreams, alloc);
|
MY_ALLOC(CFileSize, folder->UnpackSizes, (size_t)numOutStreams, alloc);
|
||||||
|
|
||||||
for (j = 0; j < numOutStreams; j++)
|
for (j = 0; j < numOutStreams; j++)
|
||||||
{
|
{
|
||||||
RINOK(SzReadSize(sd, folder->UnPackSizes + j));
|
RINOK(SzReadSize(sd, folder->UnpackSizes + j));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -640,14 +628,14 @@ static SRes SzReadUnPackInfo(
|
|||||||
SRes res;
|
SRes res;
|
||||||
Byte *crcsDefined = 0;
|
Byte *crcsDefined = 0;
|
||||||
UInt32 *crcs = 0;
|
UInt32 *crcs = 0;
|
||||||
res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp);
|
res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp);
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
for (i = 0; i < *numFolders; i++)
|
for (i = 0; i < *numFolders; i++)
|
||||||
{
|
{
|
||||||
CSzFolder *folder = (*folders) + i;
|
CSzFolder *folder = (*folders) + i;
|
||||||
folder->UnPackCRCDefined = crcsDefined[i];
|
folder->UnpackCRCDefined = crcsDefined[i];
|
||||||
folder->UnPackCRC = crcs[i];
|
folder->UnpackCRC = crcs[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IAlloc_Free(allocTemp, crcs);
|
IAlloc_Free(allocTemp, crcs);
|
||||||
@@ -660,11 +648,11 @@ static SRes SzReadUnPackInfo(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static SRes SzReadSubStreamsInfo(
|
static SRes SzReadSubStreamsInfo(
|
||||||
CSzData *sd,
|
CSzData *sd,
|
||||||
UInt32 numFolders,
|
UInt32 numFolders,
|
||||||
CSzFolder *folders,
|
CSzFolder *folders,
|
||||||
UInt32 *numUnPackStreams,
|
UInt32 *numUnpackStreams,
|
||||||
CFileSize **unPackSizes,
|
CFileSize **unpackSizes,
|
||||||
Byte **digestsDefined,
|
Byte **digestsDefined,
|
||||||
UInt32 **digests,
|
UInt32 **digests,
|
||||||
ISzAlloc *allocTemp)
|
ISzAlloc *allocTemp)
|
||||||
@@ -675,21 +663,21 @@ static SRes SzReadSubStreamsInfo(
|
|||||||
UInt32 numDigests = 0;
|
UInt32 numDigests = 0;
|
||||||
|
|
||||||
for (i = 0; i < numFolders; i++)
|
for (i = 0; i < numFolders; i++)
|
||||||
folders[i].NumUnPackStreams = 1;
|
folders[i].NumUnpackStreams = 1;
|
||||||
*numUnPackStreams = numFolders;
|
*numUnpackStreams = numFolders;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
RINOK(SzReadID(sd, &type));
|
RINOK(SzReadID(sd, &type));
|
||||||
if (type == k7zIdNumUnPackStream)
|
if (type == k7zIdNumUnpackStream)
|
||||||
{
|
{
|
||||||
*numUnPackStreams = 0;
|
*numUnpackStreams = 0;
|
||||||
for (i = 0; i < numFolders; i++)
|
for (i = 0; i < numFolders; i++)
|
||||||
{
|
{
|
||||||
UInt32 numStreams;
|
UInt32 numStreams;
|
||||||
RINOK(SzReadNumber32(sd, &numStreams));
|
RINOK(SzReadNumber32(sd, &numStreams));
|
||||||
folders[i].NumUnPackStreams = numStreams;
|
folders[i].NumUnpackStreams = numStreams;
|
||||||
*numUnPackStreams += numStreams;
|
*numUnpackStreams += numStreams;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -700,19 +688,19 @@ static SRes SzReadSubStreamsInfo(
|
|||||||
RINOK(SzSkeepData(sd));
|
RINOK(SzSkeepData(sd));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*numUnPackStreams == 0)
|
if (*numUnpackStreams == 0)
|
||||||
{
|
{
|
||||||
*unPackSizes = 0;
|
*unpackSizes = 0;
|
||||||
*digestsDefined = 0;
|
*digestsDefined = 0;
|
||||||
*digests = 0;
|
*digests = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*unPackSizes = (CFileSize *)IAlloc_Alloc(allocTemp, (size_t)*numUnPackStreams * sizeof(CFileSize));
|
*unpackSizes = (CFileSize *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(CFileSize));
|
||||||
RINOM(*unPackSizes);
|
RINOM(*unpackSizes);
|
||||||
*digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnPackStreams * sizeof(Byte));
|
*digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte));
|
||||||
RINOM(*digestsDefined);
|
RINOM(*digestsDefined);
|
||||||
*digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnPackStreams * sizeof(UInt32));
|
*digests = (UInt32 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt32));
|
||||||
RINOM(*digests);
|
RINOM(*digests);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -724,7 +712,7 @@ static SRes SzReadSubStreamsInfo(
|
|||||||
*/
|
*/
|
||||||
CFileSize sum = 0;
|
CFileSize sum = 0;
|
||||||
UInt32 j;
|
UInt32 j;
|
||||||
UInt32 numSubstreams = folders[i].NumUnPackStreams;
|
UInt32 numSubstreams = folders[i].NumUnpackStreams;
|
||||||
if (numSubstreams == 0)
|
if (numSubstreams == 0)
|
||||||
continue;
|
continue;
|
||||||
if (type == k7zIdSize)
|
if (type == k7zIdSize)
|
||||||
@@ -732,17 +720,17 @@ static SRes SzReadSubStreamsInfo(
|
|||||||
{
|
{
|
||||||
CFileSize size;
|
CFileSize size;
|
||||||
RINOK(SzReadSize(sd, &size));
|
RINOK(SzReadSize(sd, &size));
|
||||||
(*unPackSizes)[si++] = size;
|
(*unpackSizes)[si++] = size;
|
||||||
sum += size;
|
sum += size;
|
||||||
}
|
}
|
||||||
(*unPackSizes)[si++] = SzFolder_GetUnPackSize(folders + i) - sum;
|
(*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum;
|
||||||
}
|
}
|
||||||
if (type == k7zIdSize)
|
if (type == k7zIdSize)
|
||||||
{
|
{
|
||||||
RINOK(SzReadID(sd, &type));
|
RINOK(SzReadID(sd, &type));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < *numUnPackStreams; i++)
|
for (i = 0; i < *numUnpackStreams; i++)
|
||||||
{
|
{
|
||||||
(*digestsDefined)[i] = 0;
|
(*digestsDefined)[i] = 0;
|
||||||
(*digests)[i] = 0;
|
(*digests)[i] = 0;
|
||||||
@@ -751,8 +739,8 @@ static SRes SzReadSubStreamsInfo(
|
|||||||
|
|
||||||
for (i = 0; i < numFolders; i++)
|
for (i = 0; i < numFolders; i++)
|
||||||
{
|
{
|
||||||
UInt32 numSubstreams = folders[i].NumUnPackStreams;
|
UInt32 numSubstreams = folders[i].NumUnpackStreams;
|
||||||
if (numSubstreams != 1 || !folders[i].UnPackCRCDefined)
|
if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
|
||||||
numDigests += numSubstreams;
|
numDigests += numSubstreams;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -763,7 +751,7 @@ static SRes SzReadSubStreamsInfo(
|
|||||||
if (type == k7zIdCRC)
|
if (type == k7zIdCRC)
|
||||||
{
|
{
|
||||||
int digestIndex = 0;
|
int digestIndex = 0;
|
||||||
Byte *digestsDefined2 = 0;
|
Byte *digestsDefined2 = 0;
|
||||||
UInt32 *digests2 = 0;
|
UInt32 *digests2 = 0;
|
||||||
SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp);
|
SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp);
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
@@ -771,11 +759,11 @@ static SRes SzReadSubStreamsInfo(
|
|||||||
for (i = 0; i < numFolders; i++)
|
for (i = 0; i < numFolders; i++)
|
||||||
{
|
{
|
||||||
CSzFolder *folder = folders + i;
|
CSzFolder *folder = folders + i;
|
||||||
UInt32 numSubstreams = folder->NumUnPackStreams;
|
UInt32 numSubstreams = folder->NumUnpackStreams;
|
||||||
if (numSubstreams == 1 && folder->UnPackCRCDefined)
|
if (numSubstreams == 1 && folder->UnpackCRCDefined)
|
||||||
{
|
{
|
||||||
(*digestsDefined)[si] = 1;
|
(*digestsDefined)[si] = 1;
|
||||||
(*digests)[si] = folder->UnPackCRC;
|
(*digests)[si] = folder->UnpackCRC;
|
||||||
si++;
|
si++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -806,11 +794,11 @@ static SRes SzReadSubStreamsInfo(
|
|||||||
|
|
||||||
|
|
||||||
static SRes SzReadStreamsInfo(
|
static SRes SzReadStreamsInfo(
|
||||||
CSzData *sd,
|
CSzData *sd,
|
||||||
CFileSize *dataOffset,
|
CFileSize *dataOffset,
|
||||||
CSzAr *p,
|
CSzAr *p,
|
||||||
UInt32 *numUnPackStreams,
|
UInt32 *numUnpackStreams,
|
||||||
CFileSize **unPackSizes, /* allocTemp */
|
CFileSize **unpackSizes, /* allocTemp */
|
||||||
Byte **digestsDefined, /* allocTemp */
|
Byte **digestsDefined, /* allocTemp */
|
||||||
UInt32 **digests, /* allocTemp */
|
UInt32 **digests, /* allocTemp */
|
||||||
ISzAlloc *alloc,
|
ISzAlloc *alloc,
|
||||||
@@ -828,19 +816,19 @@ static SRes SzReadStreamsInfo(
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
case k7zIdPackInfo:
|
case k7zIdPackInfo:
|
||||||
{
|
{
|
||||||
RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams,
|
RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams,
|
||||||
&p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc));
|
&p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case k7zIdUnPackInfo:
|
case k7zIdUnpackInfo:
|
||||||
{
|
{
|
||||||
RINOK(SzReadUnPackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp));
|
RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case k7zIdSubStreamsInfo:
|
case k7zIdSubStreamsInfo:
|
||||||
{
|
{
|
||||||
RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders,
|
RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders,
|
||||||
numUnPackStreams, unPackSizes, digestsDefined, digests, allocTemp));
|
numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -928,18 +916,18 @@ static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, IS
|
|||||||
|
|
||||||
static SRes SzReadHeader2(
|
static SRes SzReadHeader2(
|
||||||
CSzArEx *p, /* allocMain */
|
CSzArEx *p, /* allocMain */
|
||||||
CSzData *sd,
|
CSzData *sd,
|
||||||
CFileSize **unPackSizes, /* allocTemp */
|
CFileSize **unpackSizes, /* allocTemp */
|
||||||
Byte **digestsDefined, /* allocTemp */
|
Byte **digestsDefined, /* allocTemp */
|
||||||
UInt32 **digests, /* allocTemp */
|
UInt32 **digests, /* allocTemp */
|
||||||
Byte **emptyStreamVector, /* allocTemp */
|
Byte **emptyStreamVector, /* allocTemp */
|
||||||
Byte **emptyFileVector, /* allocTemp */
|
Byte **emptyFileVector, /* allocTemp */
|
||||||
Byte **lwtVector, /* allocTemp */
|
Byte **lwtVector, /* allocTemp */
|
||||||
ISzAlloc *allocMain,
|
ISzAlloc *allocMain,
|
||||||
ISzAlloc *allocTemp)
|
ISzAlloc *allocTemp)
|
||||||
{
|
{
|
||||||
UInt64 type;
|
UInt64 type;
|
||||||
UInt32 numUnPackStreams = 0;
|
UInt32 numUnpackStreams = 0;
|
||||||
UInt32 numFiles = 0;
|
UInt32 numFiles = 0;
|
||||||
CSzFileItem *files = 0;
|
CSzFileItem *files = 0;
|
||||||
UInt32 numEmptyStreams = 0;
|
UInt32 numEmptyStreams = 0;
|
||||||
@@ -958,9 +946,9 @@ static SRes SzReadHeader2(
|
|||||||
{
|
{
|
||||||
RINOK(SzReadStreamsInfo(sd,
|
RINOK(SzReadStreamsInfo(sd,
|
||||||
&p->ArchiveInfo.DataStartPosition,
|
&p->ArchiveInfo.DataStartPosition,
|
||||||
&p->db,
|
&p->db,
|
||||||
&numUnPackStreams,
|
&numUnpackStreams,
|
||||||
unPackSizes,
|
unpackSizes,
|
||||||
digestsDefined,
|
digestsDefined,
|
||||||
digests, allocMain, allocTemp));
|
digests, allocMain, allocTemp));
|
||||||
p->ArchiveInfo.DataStartPosition += p->ArchiveInfo.StartPositionAfterHeader;
|
p->ArchiveInfo.DataStartPosition += p->ArchiveInfo.StartPositionAfterHeader;
|
||||||
@@ -1017,7 +1005,7 @@ static SRes SzReadHeader2(
|
|||||||
RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp));
|
RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case k7zIdLastWriteTime:
|
case k7zIdMTime:
|
||||||
{
|
{
|
||||||
RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
|
RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
|
||||||
RINOK(SzReadSwitch(sd));
|
RINOK(SzReadSwitch(sd));
|
||||||
@@ -1025,12 +1013,12 @@ static SRes SzReadHeader2(
|
|||||||
{
|
{
|
||||||
CSzFileItem *f = &files[i];
|
CSzFileItem *f = &files[i];
|
||||||
Byte defined = (*lwtVector)[i];
|
Byte defined = (*lwtVector)[i];
|
||||||
f->IsLastWriteTimeDefined = defined;
|
f->MTimeDefined = defined;
|
||||||
f->LastWriteTime.Low = f->LastWriteTime.High = 0;
|
f->MTime.Low = f->MTime.High = 0;
|
||||||
if (defined)
|
if (defined)
|
||||||
{
|
{
|
||||||
RINOK(SzReadUInt32(sd, &f->LastWriteTime.Low));
|
RINOK(SzReadUInt32(sd, &f->MTime.Low));
|
||||||
RINOK(SzReadUInt32(sd, &f->LastWriteTime.High));
|
RINOK(SzReadUInt32(sd, &f->MTime.High));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1055,21 +1043,21 @@ static SRes SzReadHeader2(
|
|||||||
file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
|
file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
|
||||||
if(file->HasStream)
|
if(file->HasStream)
|
||||||
{
|
{
|
||||||
file->IsDirectory = 0;
|
file->IsDir = 0;
|
||||||
file->Size = (*unPackSizes)[sizeIndex];
|
file->Size = (*unpackSizes)[sizeIndex];
|
||||||
file->FileCRC = (*digests)[sizeIndex];
|
file->FileCRC = (*digests)[sizeIndex];
|
||||||
file->IsFileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
|
file->FileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
|
||||||
sizeIndex++;
|
sizeIndex++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (*emptyFileVector == 0)
|
if (*emptyFileVector == 0)
|
||||||
file->IsDirectory = 1;
|
file->IsDir = 1;
|
||||||
else
|
else
|
||||||
file->IsDirectory = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
|
file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
|
||||||
emptyFileIndex++;
|
emptyFileIndex++;
|
||||||
file->Size = 0;
|
file->Size = 0;
|
||||||
file->IsFileCRCDefined = 0;
|
file->FileCRCDefined = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1077,50 +1065,50 @@ static SRes SzReadHeader2(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static SRes SzReadHeader(
|
static SRes SzReadHeader(
|
||||||
CSzArEx *p,
|
CSzArEx *p,
|
||||||
CSzData *sd,
|
CSzData *sd,
|
||||||
ISzAlloc *allocMain,
|
ISzAlloc *allocMain,
|
||||||
ISzAlloc *allocTemp)
|
ISzAlloc *allocTemp)
|
||||||
{
|
{
|
||||||
CFileSize *unPackSizes = 0;
|
CFileSize *unpackSizes = 0;
|
||||||
Byte *digestsDefined = 0;
|
Byte *digestsDefined = 0;
|
||||||
UInt32 *digests = 0;
|
UInt32 *digests = 0;
|
||||||
Byte *emptyStreamVector = 0;
|
Byte *emptyStreamVector = 0;
|
||||||
Byte *emptyFileVector = 0;
|
Byte *emptyFileVector = 0;
|
||||||
Byte *lwtVector = 0;
|
Byte *lwtVector = 0;
|
||||||
SRes res = SzReadHeader2(p, sd,
|
SRes res = SzReadHeader2(p, sd,
|
||||||
&unPackSizes, &digestsDefined, &digests,
|
&unpackSizes, &digestsDefined, &digests,
|
||||||
&emptyStreamVector, &emptyFileVector, &lwtVector,
|
&emptyStreamVector, &emptyFileVector, &lwtVector,
|
||||||
allocMain, allocTemp);
|
allocMain, allocTemp);
|
||||||
IAlloc_Free(allocTemp, unPackSizes);
|
IAlloc_Free(allocTemp, unpackSizes);
|
||||||
IAlloc_Free(allocTemp, digestsDefined);
|
IAlloc_Free(allocTemp, digestsDefined);
|
||||||
IAlloc_Free(allocTemp, digests);
|
IAlloc_Free(allocTemp, digests);
|
||||||
IAlloc_Free(allocTemp, emptyStreamVector);
|
IAlloc_Free(allocTemp, emptyStreamVector);
|
||||||
IAlloc_Free(allocTemp, emptyFileVector);
|
IAlloc_Free(allocTemp, emptyFileVector);
|
||||||
IAlloc_Free(allocTemp, lwtVector);
|
IAlloc_Free(allocTemp, lwtVector);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes SzReadAndDecodePackedStreams2(
|
static SRes SzReadAndDecodePackedStreams2(
|
||||||
ISzInStream *inStream,
|
ISzInStream *inStream,
|
||||||
CSzData *sd,
|
CSzData *sd,
|
||||||
CBuf *outBuffer,
|
CBuf *outBuffer,
|
||||||
CFileSize baseOffset,
|
CFileSize baseOffset,
|
||||||
CSzAr *p,
|
CSzAr *p,
|
||||||
CFileSize **unPackSizes,
|
CFileSize **unpackSizes,
|
||||||
Byte **digestsDefined,
|
Byte **digestsDefined,
|
||||||
UInt32 **digests,
|
UInt32 **digests,
|
||||||
ISzAlloc *allocTemp)
|
ISzAlloc *allocTemp)
|
||||||
{
|
{
|
||||||
|
|
||||||
UInt32 numUnPackStreams = 0;
|
UInt32 numUnpackStreams = 0;
|
||||||
CFileSize dataStartPos;
|
CFileSize dataStartPos;
|
||||||
CSzFolder *folder;
|
CSzFolder *folder;
|
||||||
CFileSize unPackSize;
|
CFileSize unpackSize;
|
||||||
SRes res;
|
SRes res;
|
||||||
|
|
||||||
RINOK(SzReadStreamsInfo(sd, &dataStartPos, p,
|
RINOK(SzReadStreamsInfo(sd, &dataStartPos, p,
|
||||||
&numUnPackStreams, unPackSizes, digestsDefined, digests,
|
&numUnpackStreams, unpackSizes, digestsDefined, digests,
|
||||||
allocTemp, allocTemp));
|
allocTemp, allocTemp));
|
||||||
|
|
||||||
dataStartPos += baseOffset;
|
dataStartPos += baseOffset;
|
||||||
@@ -1128,41 +1116,41 @@ static SRes SzReadAndDecodePackedStreams2(
|
|||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
|
||||||
folder = p->Folders;
|
folder = p->Folders;
|
||||||
unPackSize = SzFolder_GetUnPackSize(folder);
|
unpackSize = SzFolder_GetUnpackSize(folder);
|
||||||
|
|
||||||
RINOK(inStream->Seek(inStream, dataStartPos, SZ_SEEK_SET));
|
RINOK(inStream->Seek(inStream, dataStartPos, SZ_SEEK_SET));
|
||||||
|
|
||||||
if (!Buf_Create(outBuffer, (size_t)unPackSize, allocTemp))
|
if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp))
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
|
|
||||||
res = SzDecode(p->PackSizes, folder,
|
res = SzDecode(p->PackSizes, folder,
|
||||||
inStream, dataStartPos,
|
inStream, dataStartPos,
|
||||||
outBuffer->data, (size_t)unPackSize, allocTemp);
|
outBuffer->data, (size_t)unpackSize, allocTemp);
|
||||||
RINOK(res);
|
RINOK(res);
|
||||||
if (folder->UnPackCRCDefined)
|
if (folder->UnpackCRCDefined)
|
||||||
if (CrcCalc(outBuffer->data, (size_t)unPackSize) != folder->UnPackCRC)
|
if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC)
|
||||||
return SZ_ERROR_CRC;
|
return SZ_ERROR_CRC;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes SzReadAndDecodePackedStreams(
|
static SRes SzReadAndDecodePackedStreams(
|
||||||
ISzInStream *inStream,
|
ISzInStream *inStream,
|
||||||
CSzData *sd,
|
CSzData *sd,
|
||||||
CBuf *outBuffer,
|
CBuf *outBuffer,
|
||||||
CFileSize baseOffset,
|
CFileSize baseOffset,
|
||||||
ISzAlloc *allocTemp)
|
ISzAlloc *allocTemp)
|
||||||
{
|
{
|
||||||
CSzAr p;
|
CSzAr p;
|
||||||
CFileSize *unPackSizes = 0;
|
CFileSize *unpackSizes = 0;
|
||||||
Byte *digestsDefined = 0;
|
Byte *digestsDefined = 0;
|
||||||
UInt32 *digests = 0;
|
UInt32 *digests = 0;
|
||||||
SRes res;
|
SRes res;
|
||||||
SzAr_Init(&p);
|
SzAr_Init(&p);
|
||||||
res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
|
res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
|
||||||
&p, &unPackSizes, &digestsDefined, &digests,
|
&p, &unpackSizes, &digestsDefined, &digests,
|
||||||
allocTemp);
|
allocTemp);
|
||||||
SzAr_Free(&p, allocTemp);
|
SzAr_Free(&p, allocTemp);
|
||||||
IAlloc_Free(allocTemp, unPackSizes);
|
IAlloc_Free(allocTemp, unpackSizes);
|
||||||
IAlloc_Free(allocTemp, digestsDefined);
|
IAlloc_Free(allocTemp, digestsDefined);
|
||||||
IAlloc_Free(allocTemp, digests);
|
IAlloc_Free(allocTemp, digests);
|
||||||
return res;
|
return res;
|
||||||
@@ -1170,8 +1158,8 @@ static SRes SzReadAndDecodePackedStreams(
|
|||||||
|
|
||||||
static SRes SzArEx_Open2(
|
static SRes SzArEx_Open2(
|
||||||
CSzArEx *p,
|
CSzArEx *p,
|
||||||
ISzInStream *inStream,
|
ISzInStream *inStream,
|
||||||
ISzAlloc *allocMain,
|
ISzAlloc *allocMain,
|
||||||
ISzAlloc *allocTemp)
|
ISzAlloc *allocTemp)
|
||||||
{
|
{
|
||||||
Byte signature[k7zSignatureSize];
|
Byte signature[k7zSignatureSize];
|
||||||
@@ -1249,8 +1237,8 @@ static SRes SzArEx_Open2(
|
|||||||
{
|
{
|
||||||
CBuf outBuffer;
|
CBuf outBuffer;
|
||||||
Buf_Init(&outBuffer);
|
Buf_Init(&outBuffer);
|
||||||
res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer,
|
res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer,
|
||||||
p->ArchiveInfo.StartPositionAfterHeader,
|
p->ArchiveInfo.StartPositionAfterHeader,
|
||||||
allocTemp);
|
allocTemp);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
{
|
{
|
||||||
|
|||||||
+3
-3
@@ -1,5 +1,5 @@
|
|||||||
/* 7zIn.h -- 7z Input functions
|
/* 7zIn.h -- 7z Input functions
|
||||||
2008-05-05
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read 7zItem.h for license options */
|
Read 7zItem.h for license options */
|
||||||
@@ -12,7 +12,7 @@ Read 7zItem.h for license options */
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CFileSize StartPositionAfterHeader;
|
CFileSize StartPositionAfterHeader;
|
||||||
CFileSize DataStartPosition;
|
CFileSize DataStartPosition;
|
||||||
} CInArchiveInfo;
|
} CInArchiveInfo;
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
|
|||||||
CFileSize SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
|
CFileSize SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
|
||||||
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, CFileSize *resSize);
|
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, CFileSize *resSize);
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
SZ_SEEK_SET = 0,
|
SZ_SEEK_SET = 0,
|
||||||
SZ_SEEK_CUR = 1,
|
SZ_SEEK_CUR = 1,
|
||||||
|
|||||||
+12
-12
@@ -1,5 +1,5 @@
|
|||||||
/* 7zItem.c -- 7z Items
|
/* 7zItem.c -- 7z Items
|
||||||
2008-04-09
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read 7zItem.h for license options */
|
Read 7zItem.h for license options */
|
||||||
@@ -22,13 +22,13 @@ void SzFolder_Init(CSzFolder *p)
|
|||||||
p->Coders = 0;
|
p->Coders = 0;
|
||||||
p->BindPairs = 0;
|
p->BindPairs = 0;
|
||||||
p->PackStreams = 0;
|
p->PackStreams = 0;
|
||||||
p->UnPackSizes = 0;
|
p->UnpackSizes = 0;
|
||||||
p->NumCoders = 0;
|
p->NumCoders = 0;
|
||||||
p->NumBindPairs = 0;
|
p->NumBindPairs = 0;
|
||||||
p->NumPackStreams = 0;
|
p->NumPackStreams = 0;
|
||||||
p->UnPackCRCDefined = 0;
|
p->UnpackCRCDefined = 0;
|
||||||
p->UnPackCRC = 0;
|
p->UnpackCRC = 0;
|
||||||
p->NumUnPackStreams = 0;
|
p->NumUnpackStreams = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
|
void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
|
||||||
@@ -40,7 +40,7 @@ void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
|
|||||||
IAlloc_Free(alloc, p->Coders);
|
IAlloc_Free(alloc, p->Coders);
|
||||||
IAlloc_Free(alloc, p->BindPairs);
|
IAlloc_Free(alloc, p->BindPairs);
|
||||||
IAlloc_Free(alloc, p->PackStreams);
|
IAlloc_Free(alloc, p->PackStreams);
|
||||||
IAlloc_Free(alloc, p->UnPackSizes);
|
IAlloc_Free(alloc, p->UnpackSizes);
|
||||||
SzFolder_Init(p);
|
SzFolder_Init(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,25 +72,25 @@ int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CFileSize SzFolder_GetUnPackSize(CSzFolder *p)
|
CFileSize SzFolder_GetUnpackSize(CSzFolder *p)
|
||||||
{
|
{
|
||||||
int i = (int)SzFolder_GetNumOutStreams(p);
|
int i = (int)SzFolder_GetNumOutStreams(p);
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
return 0;
|
return 0;
|
||||||
for (i--; i >= 0; i--)
|
for (i--; i >= 0; i--)
|
||||||
if (SzFolder_FindBindPairForOutStream(p, i) < 0)
|
if (SzFolder_FindBindPairForOutStream(p, i) < 0)
|
||||||
return p->UnPackSizes[i];
|
return p->UnpackSizes[i];
|
||||||
/* throw 1; */
|
/* throw 1; */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SzFile_Init(CSzFileItem *p)
|
void SzFile_Init(CSzFileItem *p)
|
||||||
{
|
{
|
||||||
p->IsFileCRCDefined = 0;
|
|
||||||
p->HasStream = 1;
|
p->HasStream = 1;
|
||||||
p->IsDirectory = 0;
|
p->IsDir = 0;
|
||||||
p->IsAnti = 0;
|
p->IsAnti = 0;
|
||||||
p->IsLastWriteTimeDefined = 0;
|
p->FileCRCDefined = 0;
|
||||||
|
p->MTimeDefined = 0;
|
||||||
p->Name = 0;
|
p->Name = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-23
@@ -1,5 +1,5 @@
|
|||||||
/* 7zItem.h -- 7z Items
|
/* 7zItem.h -- 7z Items
|
||||||
2008-05-01
|
2008-07-09
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read LzmaDec.h for license options */
|
Read LzmaDec.h for license options */
|
||||||
@@ -13,9 +13,9 @@ Read LzmaDec.h for license options */
|
|||||||
/* You can define _SZ_FILE_SIZE_32, if you don't need support for files larger than 4 GB*/
|
/* You can define _SZ_FILE_SIZE_32, if you don't need support for files larger than 4 GB*/
|
||||||
|
|
||||||
#ifdef _SZ_FILE_SIZE_32
|
#ifdef _SZ_FILE_SIZE_32
|
||||||
typedef UInt32 CFileSize;
|
typedef UInt32 CFileSize;
|
||||||
#else
|
#else
|
||||||
typedef UInt64 CFileSize;
|
typedef UInt64 CFileSize;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef UInt64 CMethodID;
|
typedef UInt64 CMethodID;
|
||||||
@@ -42,21 +42,21 @@ typedef struct
|
|||||||
CSzCoderInfo *Coders;
|
CSzCoderInfo *Coders;
|
||||||
CBindPair *BindPairs;
|
CBindPair *BindPairs;
|
||||||
UInt32 *PackStreams;
|
UInt32 *PackStreams;
|
||||||
CFileSize *UnPackSizes;
|
CFileSize *UnpackSizes;
|
||||||
UInt32 NumCoders;
|
UInt32 NumCoders;
|
||||||
UInt32 NumBindPairs;
|
UInt32 NumBindPairs;
|
||||||
UInt32 NumPackStreams;
|
UInt32 NumPackStreams;
|
||||||
int UnPackCRCDefined;
|
int UnpackCRCDefined;
|
||||||
UInt32 UnPackCRC;
|
UInt32 UnpackCRC;
|
||||||
|
|
||||||
UInt32 NumUnPackStreams;
|
UInt32 NumUnpackStreams;
|
||||||
} CSzFolder;
|
} CSzFolder;
|
||||||
|
|
||||||
void SzFolder_Init(CSzFolder *p);
|
void SzFolder_Init(CSzFolder *p);
|
||||||
CFileSize SzFolder_GetUnPackSize(CSzFolder *p);
|
CFileSize SzFolder_GetUnpackSize(CSzFolder *p);
|
||||||
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
|
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
|
||||||
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
|
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
|
||||||
CFileSize SzFolder_GetUnPackSize(CSzFolder *p);
|
CFileSize SzFolder_GetUnpackSize(CSzFolder *p);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -66,25 +66,16 @@ typedef struct
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CNtfsFileTime LastWriteTime;
|
CNtfsFileTime MTime;
|
||||||
/*
|
|
||||||
CFileSize StartPos;
|
|
||||||
UInt32 Attributes;
|
|
||||||
*/
|
|
||||||
CFileSize Size;
|
CFileSize Size;
|
||||||
char *Name;
|
char *Name;
|
||||||
UInt32 FileCRC;
|
UInt32 FileCRC;
|
||||||
|
|
||||||
Byte IsFileCRCDefined;
|
|
||||||
Byte HasStream;
|
Byte HasStream;
|
||||||
Byte IsDirectory;
|
Byte IsDir;
|
||||||
Byte IsAnti;
|
Byte IsAnti;
|
||||||
Byte IsLastWriteTimeDefined;
|
Byte FileCRCDefined;
|
||||||
/*
|
Byte MTimeDefined;
|
||||||
int AreAttributesDefined;
|
|
||||||
int IsLastWriteTimeDefined;
|
|
||||||
int IsStartPosDefined;
|
|
||||||
*/
|
|
||||||
} CSzFileItem;
|
} CSzFileItem;
|
||||||
|
|
||||||
void SzFile_Init(CSzFileItem *p);
|
void SzFile_Init(CSzFileItem *p);
|
||||||
|
|||||||
+28
-28
@@ -1,5 +1,5 @@
|
|||||||
/* 7zMain.c - Test application for 7z Decoder
|
/* 7zMain.c - Test application for 7z Decoder
|
||||||
2008-04-09
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ void ConvertNumberToString(CFileSize value, char *s)
|
|||||||
{
|
{
|
||||||
char temp[32];
|
char temp[32];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
temp[pos++] = (char)('0' + (int)(value % 10));
|
temp[pos++] = (char)('0' + (int)(value % 10));
|
||||||
value /= 10;
|
value /= 10;
|
||||||
@@ -54,7 +54,7 @@ void ConvertFileTimeToString(CNtfsFileTime *ft, char *s)
|
|||||||
UInt64 v64 = ft->Low | ((UInt64)ft->High << 32);
|
UInt64 v64 = ft->Low | ((UInt64)ft->High << 32);
|
||||||
Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||||
unsigned temp;
|
unsigned temp;
|
||||||
UInt32 v;
|
UInt32 v;
|
||||||
v64 /= 10000000;
|
v64 /= 10000000;
|
||||||
sec = (unsigned)(v64 % 60);
|
sec = (unsigned)(v64 % 60);
|
||||||
v64 /= 60;
|
v64 /= 60;
|
||||||
@@ -103,15 +103,15 @@ void ConvertFileTimeToString(CNtfsFileTime *ft, char *s)
|
|||||||
#ifdef USE_WINDOWS_FUNCTIONS
|
#ifdef USE_WINDOWS_FUNCTIONS
|
||||||
/*
|
/*
|
||||||
ReadFile and WriteFile functions in Windows have BUG:
|
ReadFile and WriteFile functions in Windows have BUG:
|
||||||
If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
|
If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
|
||||||
from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
|
from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
|
||||||
(Insufficient system resources exist to complete the requested service).
|
(Insufficient system resources exist to complete the requested service).
|
||||||
*/
|
*/
|
||||||
#define kChunkSizeMax (1 << 24)
|
#define kChunkSizeMax (1 << 24)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t MyReadFile(MY_FILE_HANDLE file, void *data, size_t size)
|
size_t MyReadFile(MY_FILE_HANDLE file, void *data, size_t size)
|
||||||
{
|
{
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
#ifdef USE_WINDOWS_FUNCTIONS
|
#ifdef USE_WINDOWS_FUNCTIONS
|
||||||
@@ -132,12 +132,12 @@ size_t MyReadFile(MY_FILE_HANDLE file, void *data, size_t size)
|
|||||||
return processedSize;
|
return processedSize;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
return fread(data, 1, size, file);
|
return fread(data, 1, size, file);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t MyWriteFile(MY_FILE_HANDLE file, void *data, size_t size)
|
size_t MyWriteFile(MY_FILE_HANDLE file, void *data, size_t size)
|
||||||
{
|
{
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
#ifdef USE_WINDOWS_FUNCTIONS
|
#ifdef USE_WINDOWS_FUNCTIONS
|
||||||
@@ -158,16 +158,16 @@ size_t MyWriteFile(MY_FILE_HANDLE file, void *data, size_t size)
|
|||||||
return processedSize;
|
return processedSize;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
return fwrite(data, 1, size, file);
|
return fwrite(data, 1, size, file);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int MyCloseFile(MY_FILE_HANDLE file)
|
int MyCloseFile(MY_FILE_HANDLE file)
|
||||||
{
|
{
|
||||||
#ifdef USE_WINDOWS_FUNCTIONS
|
#ifdef USE_WINDOWS_FUNCTIONS
|
||||||
return (CloseHandle(file) != FALSE) ? 0 : 1;
|
return (CloseHandle(file) != FALSE) ? 0 : 1;
|
||||||
#else
|
#else
|
||||||
return fclose(file);
|
return fclose(file);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +205,7 @@ SRes SzFileSeekImp(void *object, CFileSize pos, ESzSeek origin)
|
|||||||
/* VC 6.0 has bug with >> 32 shifts. */
|
/* VC 6.0 has bug with >> 32 shifts. */
|
||||||
value.HighPart = 0;
|
value.HighPart = 0;
|
||||||
#endif
|
#endif
|
||||||
switch (origin)
|
switch (origin)
|
||||||
{
|
{
|
||||||
case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
|
case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
|
||||||
case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
|
case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
|
||||||
@@ -214,14 +214,14 @@ SRes SzFileSeekImp(void *object, CFileSize pos, ESzSeek origin)
|
|||||||
}
|
}
|
||||||
value.LowPart = SetFilePointer(s->File, value.LowPart, &value.HighPart, moveMethod);
|
value.LowPart = SetFilePointer(s->File, value.LowPart, &value.HighPart, moveMethod);
|
||||||
if (value.LowPart == 0xFFFFFFFF)
|
if (value.LowPart == 0xFFFFFFFF)
|
||||||
if (GetLastError() != NO_ERROR)
|
if (GetLastError() != NO_ERROR)
|
||||||
return SZ_ERROR_FAIL;
|
return SZ_ERROR_FAIL;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int moveMethod;
|
int moveMethod;
|
||||||
int res;
|
int res;
|
||||||
switch (origin)
|
switch (origin)
|
||||||
{
|
{
|
||||||
case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
|
case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
|
||||||
case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
|
case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
|
||||||
@@ -246,7 +246,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
ISzAlloc allocImp;
|
ISzAlloc allocImp;
|
||||||
ISzAlloc allocTempImp;
|
ISzAlloc allocTempImp;
|
||||||
|
|
||||||
printf("\n7z ANSI-C Decoder 4.58 Copyright (c) 1999-2008 Igor Pavlov 2008-04-09\n");
|
printf("\n7z ANSI-C Decoder 4.59 Copyright (c) 1999-2008 Igor Pavlov 2008-07-09\n");
|
||||||
if (numargs == 1)
|
if (numargs == 1)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
@@ -263,9 +263,9 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
archiveStream.File =
|
archiveStream.File =
|
||||||
#ifdef USE_WINDOWS_FUNCTIONS
|
#ifdef USE_WINDOWS_FUNCTIONS
|
||||||
CreateFileA(args[2], GENERIC_READ, FILE_SHARE_READ,
|
CreateFileA(args[2], GENERIC_READ, FILE_SHARE_READ,
|
||||||
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
if (archiveStream.File == INVALID_HANDLE_VALUE)
|
if (archiveStream.File == INVALID_HANDLE_VALUE)
|
||||||
#else
|
#else
|
||||||
@@ -311,8 +311,8 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
CSzFileItem *f = db.db.Files + i;
|
CSzFileItem *f = db.db.Files + i;
|
||||||
char s[32], t[32];
|
char s[32], t[32];
|
||||||
ConvertNumberToString(f->Size, s);
|
ConvertNumberToString(f->Size, s);
|
||||||
if (f->IsLastWriteTimeDefined)
|
if (f->MTimeDefined)
|
||||||
ConvertFileTimeToString(&f->LastWriteTime, t);
|
ConvertFileTimeToString(&f->MTime, t);
|
||||||
else
|
else
|
||||||
strcpy(t, " ");
|
strcpy(t, " ");
|
||||||
|
|
||||||
@@ -337,21 +337,21 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
size_t offset;
|
size_t offset;
|
||||||
size_t outSizeProcessed;
|
size_t outSizeProcessed;
|
||||||
CSzFileItem *f = db.db.Files + i;
|
CSzFileItem *f = db.db.Files + i;
|
||||||
if (f->IsDirectory)
|
if (f->IsDir)
|
||||||
printf("Directory ");
|
printf("Directory ");
|
||||||
else
|
else
|
||||||
printf(testCommand ?
|
printf(testCommand ?
|
||||||
"Testing ":
|
"Testing ":
|
||||||
"Extracting");
|
"Extracting");
|
||||||
printf(" %s", f->Name);
|
printf(" %s", f->Name);
|
||||||
if (f->IsDirectory)
|
if (f->IsDir)
|
||||||
{
|
{
|
||||||
printf("\n");
|
printf("\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
res = SzAr_Extract(&db, &archiveStream.InStream, i,
|
res = SzAr_Extract(&db, &archiveStream.InStream, i,
|
||||||
&blockIndex, &outBuffer, &outBufferSize,
|
&blockIndex, &outBuffer, &outBufferSize,
|
||||||
&offset, &outSizeProcessed,
|
&offset, &outSizeProcessed,
|
||||||
&allocImp, &allocTempImp);
|
&allocImp, &allocTempImp);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
@@ -368,9 +368,9 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
outputHandle =
|
outputHandle =
|
||||||
#ifdef USE_WINDOWS_FUNCTIONS
|
#ifdef USE_WINDOWS_FUNCTIONS
|
||||||
CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_READ,
|
CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_READ,
|
||||||
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
if (outputHandle == INVALID_HANDLE_VALUE)
|
if (outputHandle == INVALID_HANDLE_VALUE)
|
||||||
#else
|
#else
|
||||||
@@ -420,7 +420,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
PrintError("can not allocate memory");
|
PrintError("can not allocate memory");
|
||||||
else if (res == SZ_ERROR_CRC)
|
else if (res == SZ_ERROR_CRC)
|
||||||
PrintError("CRC error");
|
PrintError("CRC error");
|
||||||
else
|
else
|
||||||
printf("\nERROR #%d\n", res);
|
printf("\nERROR #%d\n", res);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
PROG = 7zDec
|
PROG = 7zDec
|
||||||
CXX = g++
|
CXX = g++
|
||||||
LIB =
|
LIB =
|
||||||
RM = rm -f
|
RM = rm -f
|
||||||
CFLAGS = -c -O2 -Wall
|
CFLAGS = -c -O2 -Wall
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
/* Bcj2.c -- Converter for x86 code (BCJ2)
|
/* Bcj2.c -- Converter for x86 code (BCJ2)
|
||||||
2008-04-11
|
2008-08-05
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read Bra.h for license options */
|
Read Bra.h for license options */
|
||||||
|
|
||||||
#include "Bcj2.h"
|
#include "Bcj2.h"
|
||||||
|
|
||||||
#include "Alloc.h"
|
|
||||||
|
|
||||||
#ifdef _LZMA_PROB32
|
#ifdef _LZMA_PROB32
|
||||||
#define CProb UInt32
|
#define CProb UInt32
|
||||||
#else
|
#else
|
||||||
@@ -31,14 +29,14 @@ Read Bra.h for license options */
|
|||||||
#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
|
#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
|
||||||
|
|
||||||
#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
|
#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
|
||||||
#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
|
#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
|
||||||
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
|
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
|
||||||
|
|
||||||
int Bcj2_Decode(
|
int Bcj2_Decode(
|
||||||
const Byte *buf0, SizeT size0,
|
const Byte *buf0, SizeT size0,
|
||||||
const Byte *buf1, SizeT size1,
|
const Byte *buf1, SizeT size1,
|
||||||
const Byte *buf2, SizeT size2,
|
const Byte *buf2, SizeT size2,
|
||||||
const Byte *buf3, SizeT size3,
|
const Byte *buf3, SizeT size3,
|
||||||
Byte *outBuf, SizeT outSize)
|
Byte *outBuf, SizeT outSize)
|
||||||
{
|
{
|
||||||
CProb p[256 + 2];
|
CProb p[256 + 2];
|
||||||
@@ -50,10 +48,10 @@ int Bcj2_Decode(
|
|||||||
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
|
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
|
||||||
p[i] = kBitModelTotal >> 1;
|
p[i] = kBitModelTotal >> 1;
|
||||||
|
|
||||||
buffer = buf3;
|
buffer = buf3;
|
||||||
bufferLim = buffer + size3;
|
bufferLim = buffer + size3;
|
||||||
RC_INIT2
|
RC_INIT2
|
||||||
|
|
||||||
if (outSize == 0)
|
if (outSize == 0)
|
||||||
@@ -118,7 +116,7 @@ int Bcj2_Decode(
|
|||||||
buf2 += 4;
|
buf2 += 4;
|
||||||
size2 -= 4;
|
size2 -= 4;
|
||||||
}
|
}
|
||||||
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
|
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
|
||||||
((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
|
((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
|
||||||
outBuf[outPos++] = (Byte)dest;
|
outBuf[outPos++] = (Byte)dest;
|
||||||
if (outPos == outSize)
|
if (outPos == outSize)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Bcj2.h -- Converter for x86 code (BCJ2)
|
/* Bcj2.h -- Converter for x86 code (BCJ2)
|
||||||
2008-04-11
|
2008-08-05
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read Bra.h for license options */
|
Read Bra.h for license options */
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ Read Bra.h for license options */
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Conditions:
|
Conditions:
|
||||||
outSize <= FullOutputSize,
|
outSize <= FullOutputSize,
|
||||||
where FullOutputSize is full size of output stream of x86_2 filter.
|
where FullOutputSize is full size of output stream of x86_2 filter.
|
||||||
|
|
||||||
If buf0 overlaps outBuf, there are two required conditions:
|
If buf0 overlaps outBuf, there are two required conditions:
|
||||||
@@ -23,10 +23,10 @@ Returns:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int Bcj2_Decode(
|
int Bcj2_Decode(
|
||||||
const Byte *buf0, SizeT size0,
|
const Byte *buf0, SizeT size0,
|
||||||
const Byte *buf1, SizeT size1,
|
const Byte *buf1, SizeT size1,
|
||||||
const Byte *buf2, SizeT size2,
|
const Byte *buf2, SizeT size2,
|
||||||
const Byte *buf3, SizeT size3,
|
const Byte *buf3, SizeT size3,
|
||||||
Byte *outBuf, SizeT outSize);
|
Byte *outBuf, SizeT outSize);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Bra.c -- converters for RISC code
|
/* Bra.c -- converters for RISC code
|
||||||
2008-03-19
|
2008-08-05
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read Bra.h for license options */
|
Read Bra.h for license options */
|
||||||
|
|
||||||
@@ -41,11 +41,11 @@ SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
|||||||
ip += 4;
|
ip += 4;
|
||||||
for (i = 0; i <= size; i += 2)
|
for (i = 0; i <= size; i += 2)
|
||||||
{
|
{
|
||||||
if ((data[i + 1] & 0xF8) == 0xF0 &&
|
if ((data[i + 1] & 0xF8) == 0xF0 &&
|
||||||
(data[i + 3] & 0xF8) == 0xF8)
|
(data[i + 3] & 0xF8) == 0xF8)
|
||||||
{
|
{
|
||||||
UInt32 dest;
|
UInt32 dest;
|
||||||
UInt32 src =
|
UInt32 src =
|
||||||
(((UInt32)data[i + 1] & 0x7) << 19) |
|
(((UInt32)data[i + 1] & 0x7) << 19) |
|
||||||
((UInt32)data[i + 0] << 11) |
|
((UInt32)data[i + 0] << 11) |
|
||||||
(((UInt32)data[i + 3] & 0x7) << 8) |
|
(((UInt32)data[i + 3] & 0x7) << 8) |
|
||||||
@@ -106,10 +106,10 @@ 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) |
|
||||||
((UInt32)data[i + 1] << 16) |
|
((UInt32)data[i + 1] << 16) |
|
||||||
((UInt32)data[i + 2] << 8) |
|
((UInt32)data[i + 2] << 8) |
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Bra.h -- Branch converters for executables
|
/* Bra.h -- Branch converters for executables
|
||||||
2008-03-19
|
2008-08-05
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read LzmaDec.h for license options */
|
Read LzmaDec.h for license options */
|
||||||
|
|
||||||
@@ -8,18 +8,18 @@ Read LzmaDec.h for license options */
|
|||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
These functions convert relative addresses to absolute addresses
|
These functions convert relative addresses to absolute addresses
|
||||||
in CALL instructions to increase the compression ratio.
|
in CALL instructions to increase the compression ratio.
|
||||||
|
|
||||||
In:
|
In:
|
||||||
data - data buffer
|
data - data buffer
|
||||||
size - size of data
|
size - size of data
|
||||||
ip - current virtual Instruction Pinter (IP) value
|
ip - current virtual Instruction Pinter (IP) value
|
||||||
state - state variable for x86 converter
|
state - state variable for x86 converter
|
||||||
encoding - 0 (for decoding), 1 (for encoding)
|
encoding - 0 (for decoding), 1 (for encoding)
|
||||||
|
|
||||||
Out:
|
Out:
|
||||||
state - state variable for x86 converter
|
state - state variable for x86 converter
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -41,9 +41,9 @@ in CALL instructions to increase the compression ratio.
|
|||||||
Example:
|
Example:
|
||||||
|
|
||||||
UInt32 ip = 0;
|
UInt32 ip = 0;
|
||||||
for()
|
for()
|
||||||
{
|
{
|
||||||
// size must be >= Alignment + LookAhead, if it's not last block
|
// size must be >= Alignment + LookAhead, if it's not last block
|
||||||
SizeT processed = Convert(data, size, ip, 1);
|
SizeT processed = Convert(data, size, ip, 1);
|
||||||
data += processed;
|
data += processed;
|
||||||
size -= processed;
|
size -= processed;
|
||||||
|
|||||||
+4
-4
@@ -1,16 +1,16 @@
|
|||||||
/* BraIA64.c -- converter for IA-64 code
|
/* BraIA64.c -- converter for IA-64 code
|
||||||
2008-03-19
|
2008-08-05
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read Bra.h for license options */
|
Read Bra.h for license options */
|
||||||
|
|
||||||
#include "Bra.h"
|
#include "Bra.h"
|
||||||
|
|
||||||
static const Byte kBranchTable[32] =
|
static const Byte kBranchTable[32] =
|
||||||
{
|
{
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
4, 4, 6, 6, 0, 0, 7, 7,
|
4, 4, 6, 6, 0, 0, 7, 7,
|
||||||
4, 4, 0, 0, 4, 4, 0, 0
|
4, 4, 0, 0, 4, 4, 0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
|
|||||||
+10
-10
@@ -1,5 +1,5 @@
|
|||||||
/* BwtSort.c -- BWT block sorting
|
/* BwtSort.c -- BWT block sorting
|
||||||
2008-03-26
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
@@ -22,12 +22,12 @@ Public domain */
|
|||||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||||
|
|
||||||
/* 32 Flags in UInt32 word */
|
/* 32 Flags in UInt32 word */
|
||||||
#define kNumFlagsBits 5
|
#define kNumFlagsBits 5
|
||||||
#define kNumFlagsInWord (1 << kNumFlagsBits)
|
#define kNumFlagsInWord (1 << kNumFlagsBits)
|
||||||
#define kFlagsMask (kNumFlagsInWord - 1)
|
#define kFlagsMask (kNumFlagsInWord - 1)
|
||||||
#define kAllFlags 0xFFFFFFFF
|
#define kAllFlags 0xFFFFFFFF
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define kNumBitsMax 20
|
#define kNumBitsMax 20
|
||||||
#define kIndexMask ((1 << kNumBitsMax) - 1)
|
#define kIndexMask ((1 << kNumBitsMax) - 1)
|
||||||
@@ -78,7 +78,7 @@ UInt32 NO_INLINE SortGroup(UInt32 BlockSize, UInt32 NumSortedBytes, UInt32 group
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Groups = Indices + BlockSize + BS_TEMP_SIZE;
|
Groups = Indices + BlockSize + BS_TEMP_SIZE;
|
||||||
if (groupSize <= ((UInt32)1 << NumRefBits)
|
if (groupSize <= ((UInt32)1 << NumRefBits)
|
||||||
#ifndef BLOCK_SORT_USE_HEAP_SORT
|
#ifndef BLOCK_SORT_USE_HEAP_SORT
|
||||||
&& groupSize <= range
|
&& groupSize <= range
|
||||||
#endif
|
#endif
|
||||||
@@ -117,7 +117,7 @@ UInt32 NO_INLINE SortGroup(UInt32 BlockSize, UInt32 NumSortedBytes, UInt32 group
|
|||||||
|
|
||||||
HeapSort(temp, groupSize);
|
HeapSort(temp, groupSize);
|
||||||
mask = ((1 << NumRefBits) - 1);
|
mask = ((1 << NumRefBits) - 1);
|
||||||
thereAreGroups = 0;
|
thereAreGroups = 0;
|
||||||
|
|
||||||
group = groupOffset;
|
group = groupOffset;
|
||||||
cg = (temp[0] >> NumRefBits);
|
cg = (temp[0] >> NumRefBits);
|
||||||
@@ -233,7 +233,7 @@ UInt32 NO_INLINE SortGroup(UInt32 BlockSize, UInt32 NumSortedBytes, UInt32 group
|
|||||||
}
|
}
|
||||||
else if (i == groupSize)
|
else if (i == groupSize)
|
||||||
range = (mid - left);
|
range = (mid - left);
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +307,7 @@ UInt32 NO_INLINE SortGroup(UInt32 BlockSize, UInt32 NumSortedBytes, UInt32 group
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
/* Write new Groups values and Check that there are groups */
|
/* Write new Groups values and Check that there are groups */
|
||||||
UInt32 thereAreGroups = 0;
|
UInt32 thereAreGroups = 0;
|
||||||
for (j = 0; j < groupSize; j++)
|
for (j = 0; j < groupSize; j++)
|
||||||
{
|
{
|
||||||
UInt32 group = groupOffset + j;
|
UInt32 group = groupOffset + j;
|
||||||
@@ -438,8 +438,8 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
|
|||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for(groupSize = 1;
|
for(groupSize = 1;
|
||||||
(Flags[(i + groupSize) >> kNumFlagsBits] & (1 << ((i + groupSize) & kFlagsMask))) != 0;
|
(Flags[(i + groupSize) >> kNumFlagsBits] & (1 << ((i + groupSize) & kFlagsMask))) != 0;
|
||||||
groupSize++);
|
groupSize++);
|
||||||
|
|
||||||
groupSize++;
|
groupSize++;
|
||||||
@@ -488,7 +488,7 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
|
|||||||
if (SortGroup(blockSize, NumSortedBytes, i, groupSize, NumRefBits, Indices
|
if (SortGroup(blockSize, NumSortedBytes, i, groupSize, NumRefBits, Indices
|
||||||
#ifndef BLOCK_SORT_USE_HEAP_SORT
|
#ifndef BLOCK_SORT_USE_HEAP_SORT
|
||||||
, 0, blockSize
|
, 0, blockSize
|
||||||
#endif
|
#endif
|
||||||
) != 0)
|
) != 0)
|
||||||
newLimit = i + groupSize;
|
newLimit = i + groupSize;
|
||||||
i += groupSize;
|
i += groupSize;
|
||||||
|
|||||||
+32
-11
@@ -1,16 +1,16 @@
|
|||||||
/* CpuArch.h
|
/* CpuArch.h
|
||||||
2008-03-26
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
#ifndef __CPUARCH_H
|
#ifndef __CPUARCH_H
|
||||||
#define __CPUARCH_H
|
#define __CPUARCH_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
LITTLE_ENDIAN_UNALIGN means:
|
LITTLE_ENDIAN_UNALIGN means:
|
||||||
1) CPU is LITTLE_ENDIAN
|
1) CPU is LITTLE_ENDIAN
|
||||||
2) it's allowed to make unaligned memory accesses
|
2) it's allowed to make unaligned memory accesses
|
||||||
if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know
|
if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know
|
||||||
about these properties of platform.
|
about these properties of platform.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -23,19 +23,19 @@ about these properties of platform.
|
|||||||
#define GetUi16(p) (*(const UInt16 *)(p))
|
#define GetUi16(p) (*(const UInt16 *)(p))
|
||||||
#define GetUi32(p) (*(const UInt32 *)(p))
|
#define GetUi32(p) (*(const UInt32 *)(p))
|
||||||
#define GetUi64(p) (*(const UInt64 *)(p))
|
#define GetUi64(p) (*(const UInt64 *)(p))
|
||||||
#define SetUi32(p, d) *(UInt32 *)(p) = d;
|
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define GetUi16(p) (((const Byte *)(p))[0] | \
|
#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
|
||||||
((UInt16)((const Byte *)(p))[1] << 8))
|
|
||||||
|
|
||||||
#define GetUi32(p) (((const Byte *)(p))[0] | \
|
#define GetUi32(p) ( \
|
||||||
((UInt32)((const Byte *)(p))[1] << 8 ) | \
|
((const Byte *)(p))[0] | \
|
||||||
((UInt32)((const Byte *)(p))[2] << 16) | \
|
((UInt32)((const Byte *)(p))[1] << 8) | \
|
||||||
((UInt32)((const Byte *)(p))[3] << 24))
|
((UInt32)((const Byte *)(p))[2] << 16) | \
|
||||||
|
((UInt32)((const Byte *)(p))[3] << 24))
|
||||||
|
|
||||||
#define GetUi64(p) (GetUi32(p) | (UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)
|
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
|
||||||
|
|
||||||
#define SetUi32(p, d) { UInt32 _x_ = (d); \
|
#define SetUi32(p, d) { UInt32 _x_ = (d); \
|
||||||
((Byte *)(p))[0] = (Byte)_x_; \
|
((Byte *)(p))[0] = (Byte)_x_; \
|
||||||
@@ -45,4 +45,25 @@ about these properties of platform.
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
|
||||||
|
|
||||||
|
#pragma intrinsic(_byteswap_ulong)
|
||||||
|
#pragma intrinsic(_byteswap_uint64)
|
||||||
|
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
||||||
|
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define GetBe32(p) ( \
|
||||||
|
((UInt32)((const Byte *)(p))[0] << 24) | \
|
||||||
|
((UInt32)((const Byte *)(p))[1] << 16) | \
|
||||||
|
((UInt32)((const Byte *)(p))[2] << 8) | \
|
||||||
|
((const Byte *)(p))[3] )
|
||||||
|
|
||||||
|
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+16
-16
@@ -1,5 +1,5 @@
|
|||||||
/* HuffEnc.c -- functions for Huffman encoding
|
/* HuffEnc.c -- functions for Huffman encoding
|
||||||
2008-03-26
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
@@ -24,22 +24,22 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
|
|||||||
#ifdef HUFFMAN_SPEED_OPT
|
#ifdef HUFFMAN_SPEED_OPT
|
||||||
|
|
||||||
UInt32 counters[NUM_COUNTERS];
|
UInt32 counters[NUM_COUNTERS];
|
||||||
for (i = 0; i < NUM_COUNTERS; i++)
|
for (i = 0; i < NUM_COUNTERS; i++)
|
||||||
counters[i] = 0;
|
counters[i] = 0;
|
||||||
for (i = 0; i < numSymbols; i++)
|
for (i = 0; i < numSymbols; i++)
|
||||||
{
|
{
|
||||||
UInt32 freq = freqs[i];
|
UInt32 freq = freqs[i];
|
||||||
counters[(freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1]++;
|
counters[(freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 1; i < NUM_COUNTERS; i++)
|
for (i = 1; i < NUM_COUNTERS; i++)
|
||||||
{
|
{
|
||||||
UInt32 temp = counters[i];
|
UInt32 temp = counters[i];
|
||||||
counters[i] = num;
|
counters[i] = num;
|
||||||
num += temp;
|
num += temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < numSymbols; i++)
|
for (i = 0; i < numSymbols; i++)
|
||||||
{
|
{
|
||||||
UInt32 freq = freqs[i];
|
UInt32 freq = freqs[i];
|
||||||
if (freq == 0)
|
if (freq == 0)
|
||||||
@@ -52,7 +52,7 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
for (i = 0; i < numSymbols; i++)
|
for (i = 0; i < numSymbols; i++)
|
||||||
{
|
{
|
||||||
UInt32 freq = freqs[i];
|
UInt32 freq = freqs[i];
|
||||||
if (freq == 0)
|
if (freq == 0)
|
||||||
@@ -65,7 +65,7 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num < 2)
|
if (num < 2)
|
||||||
{
|
{
|
||||||
int minCode = 0;
|
int minCode = 0;
|
||||||
int maxCode = 1;
|
int maxCode = 1;
|
||||||
@@ -85,7 +85,7 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
|
|||||||
UInt32 b, e, i;
|
UInt32 b, e, i;
|
||||||
|
|
||||||
i = b = e = 0;
|
i = b = e = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
UInt32 n, m, freq;
|
UInt32 n, m, freq;
|
||||||
n = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++;
|
n = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++;
|
||||||
@@ -96,21 +96,21 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
|
|||||||
p[m] = (p[m] & MASK) | (e << NUM_BITS);
|
p[m] = (p[m] & MASK) | (e << NUM_BITS);
|
||||||
p[e] = (p[e] & MASK) | freq;
|
p[e] = (p[e] & MASK) | freq;
|
||||||
e++;
|
e++;
|
||||||
}
|
}
|
||||||
while (num - e > 1);
|
while (num - e > 1);
|
||||||
|
|
||||||
{
|
{
|
||||||
UInt32 lenCounters[kMaxLen + 1];
|
UInt32 lenCounters[kMaxLen + 1];
|
||||||
for (i = 0; i <= kMaxLen; i++)
|
for (i = 0; i <= kMaxLen; i++)
|
||||||
lenCounters[i] = 0;
|
lenCounters[i] = 0;
|
||||||
|
|
||||||
p[--e] &= MASK;
|
p[--e] &= MASK;
|
||||||
lenCounters[1] = 2;
|
lenCounters[1] = 2;
|
||||||
while (e > 0)
|
while (e > 0)
|
||||||
{
|
{
|
||||||
UInt32 len = (p[p[--e] >> NUM_BITS] >> NUM_BITS) + 1;
|
UInt32 len = (p[p[--e] >> NUM_BITS] >> NUM_BITS) + 1;
|
||||||
p[e] = (p[e] & MASK) | (len << NUM_BITS);
|
p[e] = (p[e] & MASK) | (len << NUM_BITS);
|
||||||
if (len >= maxLen)
|
if (len >= maxLen)
|
||||||
for (len = maxLen - 1; lenCounters[len] == 0; len--);
|
for (len = maxLen - 1; lenCounters[len] == 0; len--);
|
||||||
lenCounters[len]--;
|
lenCounters[len]--;
|
||||||
lenCounters[len + 1] += 2;
|
lenCounters[len + 1] += 2;
|
||||||
@@ -119,10 +119,10 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
|
|||||||
{
|
{
|
||||||
UInt32 len;
|
UInt32 len;
|
||||||
i = 0;
|
i = 0;
|
||||||
for (len = maxLen; len != 0; len--)
|
for (len = maxLen; len != 0; len--)
|
||||||
{
|
{
|
||||||
UInt32 num;
|
UInt32 num;
|
||||||
for (num = lenCounters[len]; num != 0; num--)
|
for (num = lenCounters[len]; num != 0; num--)
|
||||||
lens[p[i++] & MASK] = (Byte)len;
|
lens[p[i++] & MASK] = (Byte)len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,14 +132,14 @@ void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymb
|
|||||||
{
|
{
|
||||||
UInt32 code = 0;
|
UInt32 code = 0;
|
||||||
UInt32 len;
|
UInt32 len;
|
||||||
for (len = 1; len <= kMaxLen; len++)
|
for (len = 1; len <= kMaxLen; len++)
|
||||||
nextCodes[len] = code = (code + lenCounters[len - 1]) << 1;
|
nextCodes[len] = code = (code + lenCounters[len - 1]) << 1;
|
||||||
}
|
}
|
||||||
/* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */
|
/* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */
|
||||||
|
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
for (i = 0; i < numSymbols; i++)
|
for (i = 0; i < numSymbols; i++)
|
||||||
p[i] = nextCodes[lens[i]]++;
|
p[i] = nextCodes[lens[i]]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-22
@@ -1,5 +1,5 @@
|
|||||||
/* LzFind.c -- Match finder for LZ algorithms
|
/* LzFind.c -- Match finder for LZ algorithms
|
||||||
2008-04-04
|
2008-08-05
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read LzFind.h for license options */
|
Read LzFind.h for license options */
|
||||||
|
|
||||||
@@ -82,8 +82,8 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
|
|||||||
|
|
||||||
void MatchFinder_MoveBlock(CMatchFinder *p)
|
void MatchFinder_MoveBlock(CMatchFinder *p)
|
||||||
{
|
{
|
||||||
memmove(p->bufferBase,
|
memmove(p->bufferBase,
|
||||||
p->buffer - p->keepSizeBefore,
|
p->buffer - p->keepSizeBefore,
|
||||||
(size_t)(p->streamPos - p->pos + p->keepSizeBefore));
|
(size_t)(p->streamPos - p->pos + p->keepSizeBefore));
|
||||||
p->buffer = p->bufferBase + p->keepSizeBefore;
|
p->buffer = p->bufferBase + p->keepSizeBefore;
|
||||||
}
|
}
|
||||||
@@ -96,7 +96,7 @@ int MatchFinder_NeedMove(CMatchFinder *p)
|
|||||||
|
|
||||||
void MatchFinder_ReadIfRequired(CMatchFinder *p)
|
void MatchFinder_ReadIfRequired(CMatchFinder *p)
|
||||||
{
|
{
|
||||||
if (p->streamEndWasReached)
|
if (p->streamEndWasReached)
|
||||||
return;
|
return;
|
||||||
if (p->keepSizeAfter >= p->streamPos - p->pos)
|
if (p->keepSizeAfter >= p->streamPos - p->pos)
|
||||||
MatchFinder_ReadBlock(p);
|
MatchFinder_ReadBlock(p);
|
||||||
@@ -159,7 +159,7 @@ static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
|
|||||||
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
|
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||||
ISzAlloc *alloc)
|
ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
@@ -174,7 +174,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
|||||||
sizeReserv = historySize >> 2;
|
sizeReserv = historySize >> 2;
|
||||||
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
|
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
|
||||||
|
|
||||||
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
|
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
|
||||||
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
|
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
|
||||||
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
|
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
|
||||||
if (LzInWindow_Create(p, sizeReserv, alloc))
|
if (LzInWindow_Create(p, sizeReserv, alloc))
|
||||||
@@ -239,7 +239,7 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
|
|||||||
{
|
{
|
||||||
UInt32 limit = kMaxValForNormalize - p->pos;
|
UInt32 limit = kMaxValForNormalize - p->pos;
|
||||||
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
|
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
|
||||||
if (limit2 < limit)
|
if (limit2 < limit)
|
||||||
limit = limit2;
|
limit = limit2;
|
||||||
limit2 = p->streamPos - p->pos;
|
limit2 = p->streamPos - p->pos;
|
||||||
if (limit2 <= p->keepSizeAfter)
|
if (limit2 <= p->keepSizeAfter)
|
||||||
@@ -249,7 +249,7 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
limit2 -= p->keepSizeAfter;
|
limit2 -= p->keepSizeAfter;
|
||||||
if (limit2 < limit)
|
if (limit2 < limit)
|
||||||
limit = limit2;
|
limit = limit2;
|
||||||
{
|
{
|
||||||
UInt32 lenLimit = p->streamPos - p->pos;
|
UInt32 lenLimit = p->streamPos - p->pos;
|
||||||
@@ -274,9 +274,9 @@ void MatchFinder_Init(CMatchFinder *p)
|
|||||||
MatchFinder_SetLimits(p);
|
MatchFinder_SetLimits(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
|
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
|
||||||
{
|
{
|
||||||
return (p->pos - p->historySize - 1) & kNormalizeMask;
|
return (p->pos - p->historySize - 1) & kNormalizeMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
|
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
|
||||||
@@ -311,8 +311,8 @@ static void MatchFinder_CheckLimits(CMatchFinder *p)
|
|||||||
MatchFinder_SetLimits(p);
|
MatchFinder_SetLimits(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
||||||
UInt32 *distances, UInt32 maxLen)
|
UInt32 *distances, UInt32 maxLen)
|
||||||
{
|
{
|
||||||
son[_cyclicBufferPos] = curMatch;
|
son[_cyclicBufferPos] = curMatch;
|
||||||
@@ -342,8 +342,8 @@ static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
||||||
UInt32 *distances, UInt32 maxLen)
|
UInt32 *distances, UInt32 maxLen)
|
||||||
{
|
{
|
||||||
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||||
@@ -397,7 +397,7 @@ UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
|
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
|
||||||
{
|
{
|
||||||
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||||
@@ -505,7 +505,7 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
delta2 = p->pos - p->hash[hash2Value];
|
delta2 = p->pos - p->hash[hash2Value];
|
||||||
curMatch = p->hash[kFix3HashSize + hashValue];
|
curMatch = p->hash[kFix3HashSize + hashValue];
|
||||||
|
|
||||||
p->hash[hash2Value] =
|
p->hash[hash2Value] =
|
||||||
p->hash[kFix3HashSize + hashValue] = p->pos;
|
p->hash[kFix3HashSize + hashValue] = p->pos;
|
||||||
|
|
||||||
|
|
||||||
@@ -522,7 +522,7 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
if (maxLen == lenLimit)
|
if (maxLen == lenLimit)
|
||||||
{
|
{
|
||||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
||||||
MOVE_POS_RET;
|
MOVE_POS_RET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GET_MATCHES_FOOTER(offset, maxLen)
|
GET_MATCHES_FOOTER(offset, maxLen)
|
||||||
@@ -567,7 +567,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
if (maxLen == lenLimit)
|
if (maxLen == lenLimit)
|
||||||
{
|
{
|
||||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
||||||
MOVE_POS_RET;
|
MOVE_POS_RET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (maxLen < 3)
|
if (maxLen < 3)
|
||||||
@@ -614,7 +614,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
if (maxLen == lenLimit)
|
if (maxLen == lenLimit)
|
||||||
{
|
{
|
||||||
p->son[p->cyclicBufferPos] = curMatch;
|
p->son[p->cyclicBufferPos] = curMatch;
|
||||||
MOVE_POS_RET;
|
MOVE_POS_RET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (maxLen < 3)
|
if (maxLen < 3)
|
||||||
@@ -640,7 +640,7 @@ static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
|||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
SKIP_HEADER(2)
|
SKIP_HEADER(2)
|
||||||
HASH2_CALC;
|
HASH2_CALC;
|
||||||
curMatch = p->hash[hashValue];
|
curMatch = p->hash[hashValue];
|
||||||
p->hash[hashValue] = p->pos;
|
p->hash[hashValue] = p->pos;
|
||||||
@@ -682,7 +682,7 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
UInt32 hash2Value, hash3Value;
|
UInt32 hash2Value, hash3Value;
|
||||||
SKIP_HEADER(4)
|
SKIP_HEADER(4)
|
||||||
HASH4_CALC;
|
HASH4_CALC;
|
||||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||||
p->hash[ hash2Value] =
|
p->hash[ hash2Value] =
|
||||||
|
|||||||
+8
-8
@@ -1,12 +1,12 @@
|
|||||||
/* LzFind.h -- Match finder for LZ algorithms
|
/* LzFind.h -- Match finder for LZ algorithms
|
||||||
2008-04-04
|
2008-08-05
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
You can use any of the following license options:
|
You can use any of the following license options:
|
||||||
1) GNU Lesser General Public License (GNU LGPL)
|
1) GNU Lesser General Public License (GNU LGPL)
|
||||||
2) Common Public License (CPL)
|
2) Common Public License (CPL)
|
||||||
3) Common Development and Distribution License (CDDL) Version 1.0
|
3) Common Development and Distribution License (CDDL) Version 1.0
|
||||||
4) Igor Pavlov, as the author of this code, expressly permits you to
|
4) Igor Pavlov, as the author of this code, expressly permits you to
|
||||||
statically or dynamically link your code (or bind by name) to this file,
|
statically or dynamically link your code (or bind by name) to this file,
|
||||||
while you keep this file unmodified.
|
while you keep this file unmodified.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -71,18 +71,18 @@ void MatchFinder_Construct(CMatchFinder *p);
|
|||||||
historySize <= 3 GB
|
historySize <= 3 GB
|
||||||
keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
|
keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
|
||||||
*/
|
*/
|
||||||
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||||
ISzAlloc *alloc);
|
ISzAlloc *alloc);
|
||||||
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
|
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
|
||||||
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
|
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
|
||||||
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
|
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
|
||||||
|
|
||||||
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
|
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
|
||||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
||||||
UInt32 *distances, UInt32 maxLen);
|
UInt32 *distances, UInt32 maxLen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Conditions:
|
Conditions:
|
||||||
Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
|
Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
|
||||||
Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
|
Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
|
||||||
|
|||||||
+47
-47
@@ -1,5 +1,5 @@
|
|||||||
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
|
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
|
||||||
2008-04-11
|
2008-08-05
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read LzFind.h for license options */
|
Read LzFind.h for license options */
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ void MtSync_GetNextBlock(CMtSync *p)
|
|||||||
/* MtSync_StopWriting must be called if Writing was started */
|
/* MtSync_StopWriting must be called if Writing was started */
|
||||||
|
|
||||||
void MtSync_StopWriting(CMtSync *p)
|
void MtSync_StopWriting(CMtSync *p)
|
||||||
{
|
{
|
||||||
UInt32 myNumBlocks = p->numProcessedBlocks;
|
UInt32 myNumBlocks = p->numProcessedBlocks;
|
||||||
if (!Thread_WasCreated(&p->thread) || p->needStart)
|
if (!Thread_WasCreated(&p->thread) || p->needStart)
|
||||||
return;
|
return;
|
||||||
@@ -233,8 +233,8 @@ void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
|
|||||||
|
|
||||||
#define NO_INLINE MY_FAST_CALL
|
#define NO_INLINE MY_FAST_CALL
|
||||||
|
|
||||||
Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
|
Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
||||||
UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)
|
UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
@@ -347,8 +347,8 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
|||||||
while (curPos < limit && size-- != 0)
|
while (curPos < limit && size-- != 0)
|
||||||
{
|
{
|
||||||
UInt32 *startDistances = distances + curPos;
|
UInt32 *startDistances = distances + curPos;
|
||||||
UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++],
|
UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++],
|
||||||
pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
|
pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
|
||||||
startDistances + 1, p->numHashBytes - 1) - startDistances);
|
startDistances + 1, p->numHashBytes - 1) - startDistances);
|
||||||
*startDistances = num - 1;
|
*startDistances = num - 1;
|
||||||
curPos += num;
|
curPos += num;
|
||||||
@@ -359,7 +359,7 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
|||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
UInt32 posRes;
|
UInt32 posRes;
|
||||||
curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
|
curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
|
||||||
distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos) , size, &posRes);
|
distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos) , size, &posRes);
|
||||||
p->hashBufPos += posRes - pos;
|
p->hashBufPos += posRes - pos;
|
||||||
cyclicBufferPos += posRes - pos;
|
cyclicBufferPos += posRes - pos;
|
||||||
@@ -454,19 +454,19 @@ void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
|
|||||||
#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
|
#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
|
||||||
|
|
||||||
static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
|
static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
|
||||||
static unsigned MY_STD_CALL BtThreadFunc2(void *p)
|
static unsigned MY_STD_CALL BtThreadFunc2(void *p)
|
||||||
{
|
{
|
||||||
Byte allocaDummy[0x180];
|
Byte allocaDummy[0x180];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
allocaDummy[i] = (Byte)i;
|
allocaDummy[i] = (Byte)i;
|
||||||
BtThreadFunc((CMatchFinderMt *)p);
|
BtThreadFunc((CMatchFinderMt *)p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
|
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc)
|
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
CMatchFinder *mf = p->MatchFinder;
|
CMatchFinder *mf = p->MatchFinder;
|
||||||
p->historySize = historySize;
|
p->historySize = historySize;
|
||||||
if (kMtBtBlockSize <= matchMaxLen * 4)
|
if (kMtBtBlockSize <= matchMaxLen * 4)
|
||||||
@@ -490,7 +490,7 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
|
|||||||
|
|
||||||
/* Call it after ReleaseStream / SetStream */
|
/* Call it after ReleaseStream / SetStream */
|
||||||
void MatchFinderMt_Init(CMatchFinderMt *p)
|
void MatchFinderMt_Init(CMatchFinderMt *p)
|
||||||
{
|
{
|
||||||
CMatchFinder *mf = p->MatchFinder;
|
CMatchFinder *mf = p->MatchFinder;
|
||||||
p->btBufPos = p->btBufPosLimit = 0;
|
p->btBufPos = p->btBufPosLimit = 0;
|
||||||
p->hashBufPos = p->hashBufPosLimit = 0;
|
p->hashBufPos = p->hashBufPosLimit = 0;
|
||||||
@@ -515,7 +515,7 @@ void MatchFinderMt_Init(CMatchFinderMt *p)
|
|||||||
|
|
||||||
/* ReleaseStream is required to finish multithreading */
|
/* ReleaseStream is required to finish multithreading */
|
||||||
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)
|
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)
|
||||||
{
|
{
|
||||||
MtSync_StopWriting(&p->btSync);
|
MtSync_StopWriting(&p->btSync);
|
||||||
/* p->MatchFinder->ReleaseStream(); */
|
/* p->MatchFinder->ReleaseStream(); */
|
||||||
}
|
}
|
||||||
@@ -534,7 +534,7 @@ void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
|
|||||||
p->btBufPosLimit = p->btBufPos = blockIndex * kMtBtBlockSize;
|
p->btBufPosLimit = p->btBufPos = blockIndex * kMtBtBlockSize;
|
||||||
p->btBufPosLimit += p->btBuf[p->btBufPos++];
|
p->btBufPosLimit += p->btBuf[p->btBufPos++];
|
||||||
p->btNumAvailBytes = p->btBuf[p->btBufPos++];
|
p->btNumAvailBytes = p->btBuf[p->btBufPos++];
|
||||||
if (p->lzPos >= kMtMaxValForNormalize - kMtBtBlockSize)
|
if (p->lzPos >= kMtMaxValForNormalize - kMtBtBlockSize)
|
||||||
MatchFinderMt_Normalize(p);
|
MatchFinderMt_Normalize(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,14 +546,14 @@ const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
|
|||||||
#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);
|
#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);
|
||||||
|
|
||||||
UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)
|
UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)
|
||||||
{
|
{
|
||||||
GET_NEXT_BLOCK_IF_REQUIRED;
|
GET_NEXT_BLOCK_IF_REQUIRED;
|
||||||
return p->btNumAvailBytes;
|
return p->btNumAvailBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index)
|
Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index)
|
||||||
{
|
{
|
||||||
return p->pointerToCurPos[index];
|
return p->pointerToCurPos[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
||||||
@@ -561,16 +561,16 @@ UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
|||||||
UInt32 hash2Value, curMatch2;
|
UInt32 hash2Value, curMatch2;
|
||||||
UInt32 *hash = p->hash;
|
UInt32 *hash = p->hash;
|
||||||
const Byte *cur = p->pointerToCurPos;
|
const Byte *cur = p->pointerToCurPos;
|
||||||
UInt32 lzPos = p->lzPos;
|
UInt32 lzPos = p->lzPos;
|
||||||
MT_HASH2_CALC
|
MT_HASH2_CALC
|
||||||
|
|
||||||
curMatch2 = hash[hash2Value];
|
curMatch2 = hash[hash2Value];
|
||||||
hash[hash2Value] = lzPos;
|
hash[hash2Value] = lzPos;
|
||||||
|
|
||||||
if (curMatch2 >= matchMinPos)
|
if (curMatch2 >= matchMinPos)
|
||||||
if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||||
{
|
{
|
||||||
*distances++ = 2;
|
*distances++ = 2;
|
||||||
*distances++ = lzPos - curMatch2 - 1;
|
*distances++ = lzPos - curMatch2 - 1;
|
||||||
}
|
}
|
||||||
return distances;
|
return distances;
|
||||||
@@ -581,31 +581,31 @@ UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
|||||||
UInt32 hash2Value, hash3Value, curMatch2, curMatch3;
|
UInt32 hash2Value, hash3Value, curMatch2, curMatch3;
|
||||||
UInt32 *hash = p->hash;
|
UInt32 *hash = p->hash;
|
||||||
const Byte *cur = p->pointerToCurPos;
|
const Byte *cur = p->pointerToCurPos;
|
||||||
UInt32 lzPos = p->lzPos;
|
UInt32 lzPos = p->lzPos;
|
||||||
MT_HASH3_CALC
|
MT_HASH3_CALC
|
||||||
|
|
||||||
curMatch2 = hash[ hash2Value];
|
curMatch2 = hash[ hash2Value];
|
||||||
curMatch3 = hash[kFix3HashSize + hash3Value];
|
curMatch3 = hash[kFix3HashSize + hash3Value];
|
||||||
|
|
||||||
hash[ hash2Value] =
|
hash[ hash2Value] =
|
||||||
hash[kFix3HashSize + hash3Value] =
|
hash[kFix3HashSize + hash3Value] =
|
||||||
lzPos;
|
lzPos;
|
||||||
|
|
||||||
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||||
{
|
{
|
||||||
distances[1] = lzPos - curMatch2 - 1;
|
distances[1] = lzPos - curMatch2 - 1;
|
||||||
if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
|
if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
|
||||||
{
|
{
|
||||||
distances[0] = 3;
|
distances[0] = 3;
|
||||||
return distances + 2;
|
return distances + 2;
|
||||||
}
|
}
|
||||||
distances[0] = 2;
|
distances[0] = 2;
|
||||||
distances += 2;
|
distances += 2;
|
||||||
}
|
}
|
||||||
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
|
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
|
||||||
{
|
{
|
||||||
*distances++ = 3;
|
*distances++ = 3;
|
||||||
*distances++ = lzPos - curMatch3 - 1;
|
*distances++ = lzPos - curMatch3 - 1;
|
||||||
}
|
}
|
||||||
return distances;
|
return distances;
|
||||||
}
|
}
|
||||||
@@ -616,16 +616,16 @@ UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
|||||||
UInt32 hash2Value, hash3Value, hash4Value, curMatch2, curMatch3, curMatch4;
|
UInt32 hash2Value, hash3Value, hash4Value, curMatch2, curMatch3, curMatch4;
|
||||||
UInt32 *hash = p->hash;
|
UInt32 *hash = p->hash;
|
||||||
const Byte *cur = p->pointerToCurPos;
|
const Byte *cur = p->pointerToCurPos;
|
||||||
UInt32 lzPos = p->lzPos;
|
UInt32 lzPos = p->lzPos;
|
||||||
MT_HASH4_CALC
|
MT_HASH4_CALC
|
||||||
|
|
||||||
curMatch2 = hash[ hash2Value];
|
curMatch2 = hash[ hash2Value];
|
||||||
curMatch3 = hash[kFix3HashSize + hash3Value];
|
curMatch3 = hash[kFix3HashSize + hash3Value];
|
||||||
curMatch4 = hash[kFix4HashSize + hash4Value];
|
curMatch4 = hash[kFix4HashSize + hash4Value];
|
||||||
|
|
||||||
hash[ hash2Value] =
|
hash[ hash2Value] =
|
||||||
hash[kFix3HashSize + hash3Value] =
|
hash[kFix3HashSize + hash3Value] =
|
||||||
hash[kFix4HashSize + hash4Value] =
|
hash[kFix4HashSize + hash4Value] =
|
||||||
lzPos;
|
lzPos;
|
||||||
|
|
||||||
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||||
@@ -667,7 +667,7 @@ UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
|||||||
#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++;
|
#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++;
|
||||||
|
|
||||||
UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||||
{
|
{
|
||||||
const UInt32 *btBuf = p->btBuf + p->btBufPos;
|
const UInt32 *btBuf = p->btBuf + p->btBufPos;
|
||||||
UInt32 len = *btBuf++;
|
UInt32 len = *btBuf++;
|
||||||
p->btBufPos += 1 + len;
|
p->btBufPos += 1 + len;
|
||||||
@@ -685,14 +685,14 @@ UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
|||||||
}
|
}
|
||||||
|
|
||||||
UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||||
{
|
{
|
||||||
const UInt32 *btBuf = p->btBuf + p->btBufPos;
|
const UInt32 *btBuf = p->btBuf + p->btBufPos;
|
||||||
UInt32 len = *btBuf++;
|
UInt32 len = *btBuf++;
|
||||||
p->btBufPos += 1 + len;
|
p->btBufPos += 1 + len;
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
{
|
{
|
||||||
if (p->btNumAvailBytes-- >= 4)
|
if (p->btNumAvailBytes-- >= 4)
|
||||||
len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
|
len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -701,7 +701,7 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
|||||||
UInt32 *distances2;
|
UInt32 *distances2;
|
||||||
p->btNumAvailBytes--;
|
p->btNumAvailBytes--;
|
||||||
distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);
|
distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
*distances2++ = *btBuf++;
|
*distances2++ = *btBuf++;
|
||||||
*distances2++ = *btBuf++;
|
*distances2++ = *btBuf++;
|
||||||
@@ -718,13 +718,13 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
|||||||
#define SKIP_FOOTER } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while(--num != 0);
|
#define SKIP_FOOTER } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while(--num != 0);
|
||||||
|
|
||||||
void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
|
void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
|
||||||
{
|
{
|
||||||
SKIP_HEADER2 { p->btNumAvailBytes--;
|
SKIP_HEADER2 { p->btNumAvailBytes--;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
|
void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
|
||||||
{
|
{
|
||||||
SKIP_HEADER(2)
|
SKIP_HEADER(2)
|
||||||
UInt32 hash2Value;
|
UInt32 hash2Value;
|
||||||
MT_HASH2_CALC
|
MT_HASH2_CALC
|
||||||
@@ -733,25 +733,25 @@ void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
|
void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
|
||||||
{
|
{
|
||||||
SKIP_HEADER(3)
|
SKIP_HEADER(3)
|
||||||
UInt32 hash2Value, hash3Value;
|
UInt32 hash2Value, hash3Value;
|
||||||
MT_HASH3_CALC
|
MT_HASH3_CALC
|
||||||
hash[kFix3HashSize + hash3Value] =
|
hash[kFix3HashSize + hash3Value] =
|
||||||
hash[ hash2Value] =
|
hash[ hash2Value] =
|
||||||
p->lzPos;
|
p->lzPos;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
|
void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
|
||||||
{
|
{
|
||||||
SKIP_HEADER(4)
|
SKIP_HEADER(4)
|
||||||
UInt32 hash2Value, hash3Value, hash4Value;
|
UInt32 hash2Value, hash3Value, hash4Value;
|
||||||
MT_HASH4_CALC
|
MT_HASH4_CALC
|
||||||
hash[kFix4HashSize + hash4Value] =
|
hash[kFix4HashSize + hash4Value] =
|
||||||
hash[kFix3HashSize + hash3Value] =
|
hash[kFix3HashSize + hash3Value] =
|
||||||
hash[ hash2Value] =
|
hash[ hash2Value] =
|
||||||
p->lzPos;
|
p->lzPos;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
|
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
|
||||||
2008-04-04
|
2008-08-05
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read LzFind.h for license options */
|
Read LzFind.h for license options */
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ typedef struct _CMatchFinderMt
|
|||||||
|
|
||||||
void MatchFinderMt_Construct(CMatchFinderMt *p);
|
void MatchFinderMt_Construct(CMatchFinderMt *p);
|
||||||
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc);
|
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc);
|
||||||
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
|
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc);
|
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc);
|
||||||
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
|
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
|
||||||
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
|
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
|
||||||
|
|||||||
+45
-45
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaDec.c -- LZMA Decoder
|
/* LzmaDec.c -- LZMA Decoder
|
||||||
2008-04-29
|
2008-08-05
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read LzmaDec.h for license options */
|
Read LzmaDec.h for license options */
|
||||||
|
|
||||||
@@ -23,8 +23,8 @@ Read LzmaDec.h for license options */
|
|||||||
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
|
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
|
||||||
#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
|
#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
|
||||||
{ UPDATE_0(p); i = (i + i); A0; } else \
|
{ UPDATE_0(p); i = (i + i); A0; } else \
|
||||||
{ UPDATE_1(p); i = (i + i) + 1; A1; }
|
{ UPDATE_1(p); i = (i + i) + 1; A1; }
|
||||||
#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
|
#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
|
||||||
|
|
||||||
#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
|
#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
|
||||||
#define TREE_DECODE(probs, limit, i) \
|
#define TREE_DECODE(probs, limit, i) \
|
||||||
@@ -53,8 +53,8 @@ Read LzmaDec.h for license options */
|
|||||||
#define UPDATE_1_CHECK range -= bound; code -= bound;
|
#define UPDATE_1_CHECK range -= bound; code -= bound;
|
||||||
#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
|
#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
|
||||||
{ UPDATE_0_CHECK; i = (i + i); A0; } else \
|
{ UPDATE_0_CHECK; i = (i + i); A0; } else \
|
||||||
{ UPDATE_1_CHECK; i = (i + i) + 1; A1; }
|
{ UPDATE_1_CHECK; i = (i + i) + 1; A1; }
|
||||||
#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
|
#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
|
||||||
#define TREE_DECODE_CHECK(probs, limit, i) \
|
#define TREE_DECODE_CHECK(probs, limit, i) \
|
||||||
{ i = 1; do { GET_BIT_CHECK(probs + i, i) } while(i < limit); i -= limit; }
|
{ i = 1; do { GET_BIT_CHECK(probs + i, i) } while(i < limit); i -= limit; }
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ Read LzmaDec.h for license options */
|
|||||||
#define LenLow (LenChoice2 + 1)
|
#define LenLow (LenChoice2 + 1)
|
||||||
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
|
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
|
||||||
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
|
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
|
||||||
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
|
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
|
||||||
|
|
||||||
|
|
||||||
#define kNumStates 12
|
#define kNumStates 12
|
||||||
@@ -120,16 +120,16 @@ StopCompilingDueBUG
|
|||||||
#define LZMA_SPEC_LEN_OFFSET (-3)
|
#define LZMA_SPEC_LEN_OFFSET (-3)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Byte kLiteralNextStates[kNumStates * 2] =
|
const Byte kLiteralNextStates[kNumStates * 2] =
|
||||||
{
|
{
|
||||||
0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,
|
0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,
|
||||||
7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
|
7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LZMA_DIC_MIN (1 << 12)
|
#define LZMA_DIC_MIN (1 << 12)
|
||||||
|
|
||||||
/* First LZMA-symbol is always decoded.
|
/* First LZMA-symbol is always decoded.
|
||||||
And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
|
And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
|
||||||
Out:
|
Out:
|
||||||
Result:
|
Result:
|
||||||
0 - OK
|
0 - OK
|
||||||
@@ -177,7 +177,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
UPDATE_0(prob);
|
UPDATE_0(prob);
|
||||||
prob = probs + Literal;
|
prob = probs + Literal;
|
||||||
if (checkDicSize != 0 || processedPos != 0)
|
if (checkDicSize != 0 || processedPos != 0)
|
||||||
prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
|
prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
|
||||||
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
|
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
|
||||||
|
|
||||||
if (state < kNumLitStates)
|
if (state < kNumLitStates)
|
||||||
@@ -208,7 +208,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
/* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
|
/* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1(prob);
|
UPDATE_1(prob);
|
||||||
prob = probs + IsRep + state;
|
prob = probs + IsRep + state;
|
||||||
@@ -249,7 +249,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
UPDATE_0(prob);
|
UPDATE_0(prob);
|
||||||
distance = rep1;
|
distance = rep1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1(prob);
|
UPDATE_1(prob);
|
||||||
prob = probs + IsRepG2 + state;
|
prob = probs + IsRepG2 + state;
|
||||||
@@ -313,7 +313,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
TREE_6_DECODE(prob, distance);
|
TREE_6_DECODE(prob, distance);
|
||||||
if (distance >= kStartPosModelIndex)
|
if (distance >= kStartPosModelIndex)
|
||||||
{
|
{
|
||||||
unsigned posSlot = (unsigned)distance;
|
unsigned posSlot = (unsigned)distance;
|
||||||
int numDirectBits = (int)(((distance >> 1) - 1));
|
int numDirectBits = (int)(((distance >> 1) - 1));
|
||||||
distance = (2 | (distance & 1));
|
distance = (2 | (distance & 1));
|
||||||
if (posSlot < kEndPosModelIndex)
|
if (posSlot < kEndPosModelIndex)
|
||||||
@@ -376,7 +376,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
rep3 = rep2;
|
rep3 = rep2;
|
||||||
rep2 = rep1;
|
rep2 = rep1;
|
||||||
rep1 = rep0;
|
rep1 = rep0;
|
||||||
rep0 = distance + 1;
|
rep0 = distance + 1;
|
||||||
if (checkDicSize == 0)
|
if (checkDicSize == 0)
|
||||||
{
|
{
|
||||||
if (distance >= processedPos)
|
if (distance >= processedPos)
|
||||||
@@ -404,8 +404,8 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
|
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
|
||||||
const Byte *lim = dest + curLen;
|
const Byte *lim = dest + curLen;
|
||||||
dicPos += curLen;
|
dicPos += curLen;
|
||||||
do
|
do
|
||||||
*(dest) = (Byte)*(dest + src);
|
*(dest) = (Byte)*(dest + src);
|
||||||
while (++dest != lim);
|
while (++dest != lim);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -491,7 +491,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
DUMMY_ERROR, /* unexpected end of input stream */
|
DUMMY_ERROR, /* unexpected end of input stream */
|
||||||
DUMMY_LIT,
|
DUMMY_LIT,
|
||||||
@@ -523,8 +523,8 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
|||||||
|
|
||||||
prob = probs + Literal;
|
prob = probs + Literal;
|
||||||
if (p->checkDicSize != 0 || p->processedPos != 0)
|
if (p->checkDicSize != 0 || p->processedPos != 0)
|
||||||
prob += (LZMA_LIT_SIZE *
|
prob += (LZMA_LIT_SIZE *
|
||||||
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
|
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
|
||||||
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
|
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
|
||||||
|
|
||||||
if (state < kNumLitStates)
|
if (state < kNumLitStates)
|
||||||
@@ -534,7 +534,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
|
unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
|
||||||
((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
|
((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
|
||||||
unsigned offs = 0x100;
|
unsigned offs = 0x100;
|
||||||
unsigned symbol = 1;
|
unsigned symbol = 1;
|
||||||
@@ -551,7 +551,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
|||||||
}
|
}
|
||||||
res = DUMMY_LIT;
|
res = DUMMY_LIT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned len;
|
unsigned len;
|
||||||
UPDATE_1_CHECK;
|
UPDATE_1_CHECK;
|
||||||
@@ -592,7 +592,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
|||||||
{
|
{
|
||||||
UPDATE_0_CHECK;
|
UPDATE_0_CHECK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1_CHECK;
|
UPDATE_1_CHECK;
|
||||||
prob = probs + IsRepG2 + state;
|
prob = probs + IsRepG2 + state;
|
||||||
@@ -646,7 +646,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
|||||||
{
|
{
|
||||||
unsigned posSlot;
|
unsigned posSlot;
|
||||||
prob = probs + PosSlot +
|
prob = probs + PosSlot +
|
||||||
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
|
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
|
||||||
kNumPosSlotBits);
|
kNumPosSlotBits);
|
||||||
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
|
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
|
||||||
if (posSlot >= kStartPosModelIndex)
|
if (posSlot >= kStartPosModelIndex)
|
||||||
@@ -697,11 +697,11 @@ static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
|
|||||||
p->needFlush = 0;
|
p->needFlush = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
||||||
{
|
{
|
||||||
p->needFlush = 1;
|
p->needFlush = 1;
|
||||||
p->remainLen = 0;
|
p->remainLen = 0;
|
||||||
p->tempBufSize = 0;
|
p->tempBufSize = 0;
|
||||||
|
|
||||||
if (initDic)
|
if (initDic)
|
||||||
{
|
{
|
||||||
@@ -713,9 +713,9 @@ void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
|||||||
p->needInitState = 1;
|
p->needInitState = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LzmaDec_Init(CLzmaDec *p)
|
void LzmaDec_Init(CLzmaDec *p)
|
||||||
{
|
{
|
||||||
p->dicPos = 0;
|
p->dicPos = 0;
|
||||||
LzmaDec_InitDicAndState(p, True, True);
|
LzmaDec_InitDicAndState(p, True, True);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,13 +725,13 @@ static void LzmaDec_InitStateReal(CLzmaDec *p)
|
|||||||
UInt32 i;
|
UInt32 i;
|
||||||
CLzmaProb *probs = p->probs;
|
CLzmaProb *probs = p->probs;
|
||||||
for (i = 0; i < numProbs; i++)
|
for (i = 0; i < numProbs; i++)
|
||||||
probs[i] = kBitModelTotal >> 1;
|
probs[i] = kBitModelTotal >> 1;
|
||||||
p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
|
p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
|
||||||
p->state = 0;
|
p->state = 0;
|
||||||
p->needInitState = 0;
|
p->needInitState = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
|
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
|
||||||
ELzmaFinishMode finishMode, ELzmaStatus *status)
|
ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||||
{
|
{
|
||||||
SizeT inSize = *srcLen;
|
SizeT inSize = *srcLen;
|
||||||
@@ -847,7 +847,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
|
|||||||
p->tempBufSize = 0;
|
p->tempBufSize = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p->code == 0)
|
if (p->code == 0)
|
||||||
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
||||||
return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
|
return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
|
||||||
}
|
}
|
||||||
@@ -892,16 +892,16 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
|
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->probs);
|
alloc->Free(alloc, p->probs);
|
||||||
p->probs = 0;
|
p->probs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
|
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->dic);
|
alloc->Free(alloc, p->dic);
|
||||||
p->dic = 0;
|
p->dic = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
|
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
|
||||||
@@ -912,7 +912,7 @@ void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
|
|||||||
|
|
||||||
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
|
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
|
||||||
{
|
{
|
||||||
UInt32 dicSize;
|
UInt32 dicSize;
|
||||||
Byte d;
|
Byte d;
|
||||||
|
|
||||||
if (size < LZMA_PROPS_SIZE)
|
if (size < LZMA_PROPS_SIZE)
|
||||||
@@ -982,7 +982,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
|
|||||||
}
|
}
|
||||||
|
|
||||||
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||||
ELzmaStatus *status, ISzAlloc *alloc)
|
ELzmaStatus *status, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
CLzmaDec p;
|
CLzmaDec p;
|
||||||
|
|||||||
+29
-29
@@ -1,12 +1,12 @@
|
|||||||
/* LzmaDec.h -- LZMA Decoder
|
/* LzmaDec.h -- LZMA Decoder
|
||||||
2008-04-29
|
2008-08-05
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
You can use any of the following license options:
|
You can use any of the following license options:
|
||||||
1) GNU Lesser General Public License (GNU LGPL)
|
1) GNU Lesser General Public License (GNU LGPL)
|
||||||
2) Common Public License (CPL)
|
2) Common Public License (CPL)
|
||||||
3) Common Development and Distribution License (CDDL) Version 1.0
|
3) Common Development and Distribution License (CDDL) Version 1.0
|
||||||
4) Igor Pavlov, as the author of this code, expressly permits you to
|
4) Igor Pavlov, as the author of this code, expressly permits you to
|
||||||
statically or dynamically link your code (or bind by name) to this file,
|
statically or dynamically link your code (or bind by name) to this file,
|
||||||
while you keep this file unmodified.
|
while you keep this file unmodified.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ You can use any of the following license options:
|
|||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
/* #define _LZMA_PROB32 */
|
/* #define _LZMA_PROB32 */
|
||||||
/* _LZMA_PROB32 can increase the speed on some CPUs,
|
/* _LZMA_PROB32 can increase the speed on some CPUs,
|
||||||
but memory usage for CLzmaDec::probs will be doubled in that case */
|
but memory usage for CLzmaDec::probs will be doubled in that case */
|
||||||
|
|
||||||
#ifdef _LZMA_PROB32
|
#ifdef _LZMA_PROB32
|
||||||
@@ -26,7 +26,7 @@ You can use any of the following license options:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* ---------- LZMA Properties ---------- */
|
/* ---------- LZMA Properties ---------- */
|
||||||
|
|
||||||
#define LZMA_PROPS_SIZE 5
|
#define LZMA_PROPS_SIZE 5
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ Returns:
|
|||||||
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
|
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
|
||||||
|
|
||||||
|
|
||||||
/* ---------- LZMA Decoder state ---------- */
|
/* ---------- LZMA Decoder state ---------- */
|
||||||
|
|
||||||
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
|
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
|
||||||
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
|
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
|
||||||
@@ -81,15 +81,15 @@ void LzmaDec_Init(CLzmaDec *p);
|
|||||||
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
||||||
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
|
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
LZMA_FINISH_ANY, /* finish at any point */
|
LZMA_FINISH_ANY, /* finish at any point */
|
||||||
LZMA_FINISH_END /* block must be finished at the end */
|
LZMA_FINISH_END /* block must be finished at the end */
|
||||||
} ELzmaFinishMode;
|
} ELzmaFinishMode;
|
||||||
|
|
||||||
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
|
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
|
||||||
|
|
||||||
You must use LZMA_FINISH_END, when you know that current output buffer
|
You must use LZMA_FINISH_END, when you know that current output buffer
|
||||||
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
|
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
|
||||||
|
|
||||||
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
|
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
|
||||||
@@ -99,36 +99,36 @@ typedef enum
|
|||||||
You can use multiple checks to test data integrity after full decompression:
|
You can use multiple checks to test data integrity after full decompression:
|
||||||
1) Check Result and "status" variable.
|
1) Check Result and "status" variable.
|
||||||
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
|
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
|
||||||
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
|
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
|
||||||
You must use correct finish mode in that case. */
|
You must use correct finish mode in that case. */
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
||||||
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
||||||
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
|
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
|
||||||
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
|
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
|
||||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
|
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
|
||||||
} ELzmaStatus;
|
} ELzmaStatus;
|
||||||
|
|
||||||
/* ELzmaStatus is used only as output value for function call */
|
/* ELzmaStatus is used only as output value for function call */
|
||||||
|
|
||||||
|
|
||||||
/* ---------- Interfaces ---------- */
|
/* ---------- Interfaces ---------- */
|
||||||
|
|
||||||
/* There are 3 levels of interfaces:
|
/* There are 3 levels of interfaces:
|
||||||
1) Dictionary Interface
|
1) Dictionary Interface
|
||||||
2) Buffer Interface
|
2) Buffer Interface
|
||||||
3) One Call Interface
|
3) One Call Interface
|
||||||
You can select any of these interfaces, but don't mix functions from different
|
You can select any of these interfaces, but don't mix functions from different
|
||||||
groups for same object. */
|
groups for same object. */
|
||||||
|
|
||||||
|
|
||||||
/* There are two variants to allocate state for Dictionary Interface:
|
/* There are two variants to allocate state for Dictionary Interface:
|
||||||
1) LzmaDec_Allocate / LzmaDec_Free
|
1) LzmaDec_Allocate / LzmaDec_Free
|
||||||
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
|
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
|
||||||
You can use variant 2, if you set dictionary buffer manually.
|
You can use variant 2, if you set dictionary buffer manually.
|
||||||
For Buffer Interface you must always use variant 1.
|
For Buffer Interface you must always use variant 1.
|
||||||
|
|
||||||
LzmaDec_Allocate* can return:
|
LzmaDec_Allocate* can return:
|
||||||
SZ_OK
|
SZ_OK
|
||||||
@@ -142,9 +142,9 @@ void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
|
|||||||
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
|
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
|
||||||
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
||||||
|
|
||||||
/* ---------- Dictionary Interface ---------- */
|
/* ---------- Dictionary Interface ---------- */
|
||||||
|
|
||||||
/* You can use it, if you want to eliminate the overhead for data copying from
|
/* You can use it, if you want to eliminate the overhead for data copying from
|
||||||
dictionary to some other external buffer.
|
dictionary to some other external buffer.
|
||||||
You must work with CLzmaDec variables directly in this interface.
|
You must work with CLzmaDec variables directly in this interface.
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
|||||||
/* LzmaDec_DecodeToDic
|
/* LzmaDec_DecodeToDic
|
||||||
|
|
||||||
The decoding to internal dictionary buffer (CLzmaDec::dic).
|
The decoding to internal dictionary buffer (CLzmaDec::dic).
|
||||||
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
|
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
|
||||||
|
|
||||||
finishMode:
|
finishMode:
|
||||||
It has meaning only if the decoding reaches output limit (dicLimit).
|
It has meaning only if the decoding reaches output limit (dicLimit).
|
||||||
@@ -177,34 +177,34 @@ Returns:
|
|||||||
SZ_OK
|
SZ_OK
|
||||||
status:
|
status:
|
||||||
LZMA_STATUS_FINISHED_WITH_MARK
|
LZMA_STATUS_FINISHED_WITH_MARK
|
||||||
LZMA_STATUS_NOT_FINISHED
|
LZMA_STATUS_NOT_FINISHED
|
||||||
LZMA_STATUS_NEEDS_MORE_INPUT
|
LZMA_STATUS_NEEDS_MORE_INPUT
|
||||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||||
SZ_ERROR_DATA - Data error
|
SZ_ERROR_DATA - Data error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
|
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
|
||||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||||
|
|
||||||
|
|
||||||
/* ---------- Buffer Interface ---------- */
|
/* ---------- Buffer Interface ---------- */
|
||||||
|
|
||||||
/* It's zlib-like interface.
|
/* It's zlib-like interface.
|
||||||
See LzmaDec_DecodeToDic description for information about STEPS and return results,
|
See LzmaDec_DecodeToDic description for information about STEPS and return results,
|
||||||
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
|
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
|
||||||
to work with CLzmaDec variables manually.
|
to work with CLzmaDec variables manually.
|
||||||
|
|
||||||
finishMode:
|
finishMode:
|
||||||
It has meaning only if the decoding reaches output limit (*destLen).
|
It has meaning only if the decoding reaches output limit (*destLen).
|
||||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
||||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||||
|
|
||||||
|
|
||||||
/* ---------- One Call Interface ---------- */
|
/* ---------- One Call Interface ---------- */
|
||||||
|
|
||||||
/* LzmaDecode
|
/* LzmaDecode
|
||||||
|
|
||||||
@@ -217,7 +217,7 @@ Returns:
|
|||||||
SZ_OK
|
SZ_OK
|
||||||
status:
|
status:
|
||||||
LZMA_STATUS_FINISHED_WITH_MARK
|
LZMA_STATUS_FINISHED_WITH_MARK
|
||||||
LZMA_STATUS_NOT_FINISHED
|
LZMA_STATUS_NOT_FINISHED
|
||||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||||
SZ_ERROR_DATA - Data error
|
SZ_ERROR_DATA - Data error
|
||||||
SZ_ERROR_MEM - Memory allocation error
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
@@ -226,7 +226,7 @@ Returns:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||||
ELzmaStatus *status, ISzAlloc *alloc);
|
ELzmaStatus *status, ISzAlloc *alloc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+223
-280
File diff suppressed because it is too large
Load Diff
+10
-10
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaEnc.h -- LZMA Encoder
|
/* LzmaEnc.h -- LZMA Encoder
|
||||||
2008-04-27
|
2008-08-05
|
||||||
Copyright (c) 1999-2008 Igor Pavlov
|
Copyright (c) 1999-2008 Igor Pavlov
|
||||||
Read LzFind.h for license options */
|
Read LzFind.h for license options */
|
||||||
|
|
||||||
@@ -12,13 +12,13 @@ Read LzFind.h for license options */
|
|||||||
|
|
||||||
typedef struct _CLzmaEncProps
|
typedef struct _CLzmaEncProps
|
||||||
{
|
{
|
||||||
int level; /* 0 <= level <= 9 */
|
int level; /* 0 <= level <= 9 */
|
||||||
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
|
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
|
||||||
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
|
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
|
||||||
default = (1 << 24) */
|
default = (1 << 24) */
|
||||||
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 */
|
||||||
int algo; /* 0 - fast, 1 - normal, default = 1 */
|
int algo; /* 0 - fast, 1 - normal, default = 1 */
|
||||||
int fb; /* 5 <= fb <= 273, default = 32 */
|
int fb; /* 5 <= fb <= 273, default = 32 */
|
||||||
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
|
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
|
||||||
@@ -38,7 +38,7 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
|
|||||||
/* LzmaEnc_* functions can return the following exit codes:
|
/* LzmaEnc_* functions can return the following exit codes:
|
||||||
Returns:
|
Returns:
|
||||||
SZ_OK - OK
|
SZ_OK - OK
|
||||||
SZ_ERROR_MEM - Memory allocation error
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
SZ_ERROR_PARAM - Incorrect paramater in props
|
SZ_ERROR_PARAM - Incorrect paramater in props
|
||||||
SZ_ERROR_WRITE - Write callback error.
|
SZ_ERROR_WRITE - Write callback error.
|
||||||
SZ_ERROR_PROGRESS - some break from progress callback
|
SZ_ERROR_PROGRESS - some break from progress callback
|
||||||
@@ -51,7 +51,7 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
|
|||||||
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
|
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||||
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
|
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
|
||||||
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
|
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
|
||||||
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
|
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||||
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||||
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||||
@@ -61,14 +61,14 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte
|
|||||||
/* LzmaEncode
|
/* LzmaEncode
|
||||||
Return code:
|
Return code:
|
||||||
SZ_OK - OK
|
SZ_OK - OK
|
||||||
SZ_ERROR_MEM - Memory allocation error
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
SZ_ERROR_PARAM - Incorrect paramater
|
SZ_ERROR_PARAM - Incorrect paramater
|
||||||
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||||
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+6
-6
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaLib.c -- LZMA library wrapper
|
/* LzmaLib.c -- LZMA library wrapper
|
||||||
2008-04-07
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
@@ -16,9 +16,9 @@ MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned cha
|
|||||||
unsigned char *outProps, size_t *outPropsSize,
|
unsigned char *outProps, size_t *outPropsSize,
|
||||||
int level, /* 0 <= level <= 9, default = 5 */
|
int level, /* 0 <= level <= 9, default = 5 */
|
||||||
unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */
|
unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */
|
||||||
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 */
|
||||||
int fb, /* 5 <= fb <= 273, default = 32 */
|
int fb, /* 5 <= fb <= 273, default = 32 */
|
||||||
int numThreads /* 1 or 2, default = 2 */
|
int numThreads /* 1 or 2, default = 2 */
|
||||||
)
|
)
|
||||||
@@ -33,12 +33,12 @@ MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned cha
|
|||||||
props.fb = fb;
|
props.fb = fb;
|
||||||
props.numThreads = numThreads;
|
props.numThreads = numThreads;
|
||||||
|
|
||||||
return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0,
|
return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0,
|
||||||
NULL, &g_Alloc, &g_Alloc);
|
NULL, &g_Alloc, &g_Alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
|
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
|
||||||
const unsigned char *props, size_t propsSize)
|
const unsigned char *props, size_t propsSize)
|
||||||
{
|
{
|
||||||
ELzmaStatus status;
|
ELzmaStatus status;
|
||||||
|
|||||||
+29
-29
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaLib.h -- LZMA library interface
|
/* LzmaLib.h -- LZMA library interface
|
||||||
2008-04-11
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ LZMA properties (5 bytes) format
|
|||||||
LzmaCompress
|
LzmaCompress
|
||||||
------------
|
------------
|
||||||
|
|
||||||
outPropsSize -
|
outPropsSize -
|
||||||
In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
|
In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
|
||||||
Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
|
Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ outPropsSize -
|
|||||||
level - compression level: 0 <= level <= 9;
|
level - compression level: 0 <= level <= 9;
|
||||||
|
|
||||||
level dictSize algo fb
|
level dictSize algo fb
|
||||||
0: 16 KB 0 32
|
0: 16 KB 0 32
|
||||||
1: 64 KB 0 32
|
1: 64 KB 0 32
|
||||||
2: 256 KB 0 32
|
2: 256 KB 0 32
|
||||||
3: 1 MB 0 32
|
3: 1 MB 0 32
|
||||||
@@ -60,40 +60,40 @@ level - compression level: 0 <= level <= 9;
|
|||||||
algo = 0 means fast method
|
algo = 0 means fast method
|
||||||
algo = 1 means normal method
|
algo = 1 means normal method
|
||||||
|
|
||||||
dictSize - The dictionary size in bytes. The maximum value is
|
dictSize - The dictionary size in bytes. The maximum value is
|
||||||
128 MB = (1 << 27) bytes for 32-bit version
|
128 MB = (1 << 27) bytes for 32-bit version
|
||||||
1 GB = (1 << 30) bytes for 64-bit version
|
1 GB = (1 << 30) bytes for 64-bit version
|
||||||
The default value is 16 MB = (1 << 24) bytes.
|
The default value is 16 MB = (1 << 24) bytes.
|
||||||
It's recommended to use the dictionary that is larger than 4 KB and
|
It's recommended to use the dictionary that is larger than 4 KB and
|
||||||
that can be calculated as (1 << N) or (3 << N) sizes.
|
that can be calculated as (1 << N) or (3 << N) sizes.
|
||||||
|
|
||||||
lc - The number of literal context bits (high bits of previous literal).
|
lc - The number of literal context bits (high bits of previous literal).
|
||||||
It can be in the range from 0 to 8. The default value is 3.
|
It can be in the range from 0 to 8. The default value is 3.
|
||||||
Sometimes lc=4 gives the gain for big files.
|
Sometimes lc=4 gives the gain for big files.
|
||||||
|
|
||||||
lp - The number of literal pos bits (low bits of current position for literals).
|
lp - The number of literal pos bits (low bits of current position for literals).
|
||||||
It can be in the range from 0 to 4. The default value is 0.
|
It can be in the range from 0 to 4. The default value is 0.
|
||||||
The lp switch is intended for periodical data when the period is equal to 2^lp.
|
The lp switch is intended for periodical data when the period is equal to 2^lp.
|
||||||
For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's
|
For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's
|
||||||
better to set lc=0, if you change lp switch.
|
better to set lc=0, if you change lp switch.
|
||||||
|
|
||||||
pb - The number of pos bits (low bits of current position).
|
pb - The number of pos bits (low bits of current position).
|
||||||
It can be in the range from 0 to 4. The default value is 2.
|
It can be in the range from 0 to 4. The default value is 2.
|
||||||
The pb switch is intended for periodical data when the period is equal 2^pb.
|
The pb switch is intended for periodical data when the period is equal 2^pb.
|
||||||
|
|
||||||
fb - Word size (the number of fast bytes).
|
fb - Word size (the number of fast bytes).
|
||||||
It can be in the range from 5 to 273. The default value is 32.
|
It can be in the range from 5 to 273. The default value is 32.
|
||||||
Usually, a big number gives a little bit better compression ratio and
|
Usually, a big number gives a little bit better compression ratio and
|
||||||
slower compression process.
|
slower compression process.
|
||||||
|
|
||||||
numThreads - The number of thereads. 1 or 2. The default value is 2.
|
numThreads - The number of thereads. 1 or 2. The default value is 2.
|
||||||
Fast mode (algo = 0) can use only 1 thread.
|
Fast mode (algo = 0) can use only 1 thread.
|
||||||
|
|
||||||
Out:
|
Out:
|
||||||
destLen - processed output size
|
destLen - processed output size
|
||||||
Returns:
|
Returns:
|
||||||
SZ_OK - OK
|
SZ_OK - OK
|
||||||
SZ_ERROR_MEM - Memory allocation error
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
SZ_ERROR_PARAM - Incorrect paramater
|
SZ_ERROR_PARAM - Incorrect paramater
|
||||||
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||||
@@ -103,24 +103,24 @@ MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char
|
|||||||
unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
|
unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
|
||||||
int level, /* 0 <= level <= 9, default = 5 */
|
int level, /* 0 <= level <= 9, default = 5 */
|
||||||
unsigned dictSize, /* default = (1 << 24) */
|
unsigned dictSize, /* default = (1 << 24) */
|
||||||
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 */
|
||||||
int fb, /* 5 <= fb <= 273, default = 32 */
|
int fb, /* 5 <= fb <= 273, default = 32 */
|
||||||
int numThreads /* 1 or 2, default = 2 */
|
int numThreads /* 1 or 2, default = 2 */
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
LzmaUncompress
|
LzmaUncompress
|
||||||
--------------
|
--------------
|
||||||
In:
|
In:
|
||||||
dest - output data
|
dest - output data
|
||||||
destLen - output data size
|
destLen - output data size
|
||||||
src - input data
|
src - input data
|
||||||
srcLen - input data size
|
srcLen - input data size
|
||||||
Out:
|
Out:
|
||||||
destLen - processed output size
|
destLen - processed output size
|
||||||
srcLen - processed input size
|
srcLen - processed input size
|
||||||
Returns:
|
Returns:
|
||||||
SZ_OK - OK
|
SZ_OK - OK
|
||||||
SZ_ERROR_DATA - Data error
|
SZ_ERROR_DATA - Data error
|
||||||
@@ -129,7 +129,7 @@ Returns:
|
|||||||
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src)
|
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
|
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
|
||||||
const unsigned char *props, size_t propsSize);
|
const unsigned char *props, size_t propsSize);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@ OBJS = \
|
|||||||
|
|
||||||
!include "../../CPP/Build.mak"
|
!include "../../CPP/Build.mak"
|
||||||
|
|
||||||
$(SLIBPATH): $O $(OBJS)
|
$(SLIBPATH): $O $(OBJS)
|
||||||
lib -out:$(SLIBPATH) $(OBJS) $(LIBS)
|
lib -out:$(SLIBPATH) $(OBJS) $(LIBS)
|
||||||
|
|
||||||
$(LIB_OBJS): $(*B).c
|
$(LIB_OBJS): $(*B).c
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Lzma86Dec.h -- LZMA + x86 (BCJ) Filter Decoder
|
/* Lzma86Dec.h -- LZMA + x86 (BCJ) Filter Decoder
|
||||||
2008-04-07
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
@@ -10,10 +10,10 @@ Public domain */
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Lzma86_GetUnpackSize:
|
Lzma86_GetUnpackSize:
|
||||||
In:
|
In:
|
||||||
src - input data
|
src - input data
|
||||||
srcLen - input data size
|
srcLen - input data size
|
||||||
Out:
|
Out:
|
||||||
unpackSize - size of uncompressed stream
|
unpackSize - size of uncompressed stream
|
||||||
Return code:
|
Return code:
|
||||||
SZ_OK - OK
|
SZ_OK - OK
|
||||||
@@ -24,14 +24,14 @@ SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize);
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Lzma86_Decode:
|
Lzma86_Decode:
|
||||||
In:
|
In:
|
||||||
dest - output data
|
dest - output data
|
||||||
destLen - output data size
|
destLen - output data size
|
||||||
src - input data
|
src - input data
|
||||||
srcLen - input data size
|
srcLen - input data size
|
||||||
Out:
|
Out:
|
||||||
destLen - processed output size
|
destLen - processed output size
|
||||||
srcLen - processed input size
|
srcLen - processed input size
|
||||||
Return code:
|
Return code:
|
||||||
SZ_OK - OK
|
SZ_OK - OK
|
||||||
SZ_ERROR_DATA - Data error
|
SZ_ERROR_DATA - Data error
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
|
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
|
||||||
2008-04-07
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
|||||||
#define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE)
|
#define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE)
|
||||||
#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
|
#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
|
||||||
|
|
||||||
int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
||||||
int level, UInt32 dictSize, int filterMode)
|
int level, UInt32 dictSize, int filterMode)
|
||||||
{
|
{
|
||||||
size_t outSize2 = *destLen;
|
size_t outSize2 = *destLen;
|
||||||
@@ -32,7 +32,7 @@ int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
|||||||
props.level = level;
|
props.level = level;
|
||||||
props.dictSize = dictSize;
|
props.dictSize = dictSize;
|
||||||
|
|
||||||
*destLen = 0;
|
*destLen = 0;
|
||||||
if (outSize2 < LZMA86_HEADER_SIZE)
|
if (outSize2 < LZMA86_HEADER_SIZE)
|
||||||
return SZ_ERROR_OUTPUT_EOF;
|
return SZ_ERROR_OUTPUT_EOF;
|
||||||
|
|
||||||
@@ -66,8 +66,8 @@ int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
|||||||
Bool bestIsFiltered = False;
|
Bool bestIsFiltered = False;
|
||||||
|
|
||||||
/* passes for SZ_FILTER_AUTO:
|
/* passes for SZ_FILTER_AUTO:
|
||||||
0 - BCJ + LZMA
|
0 - BCJ + LZMA
|
||||||
1 - LZMA
|
1 - LZMA
|
||||||
2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.
|
2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.
|
||||||
*/
|
*/
|
||||||
int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
|
int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
|
||||||
@@ -84,9 +84,9 @@ int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
|||||||
if (useFilter && i == 0)
|
if (useFilter && i == 0)
|
||||||
curModeIsFiltered = True;
|
curModeIsFiltered = True;
|
||||||
|
|
||||||
curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed,
|
curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed,
|
||||||
curModeIsFiltered ? filteredStream : src, srcLen,
|
curModeIsFiltered ? filteredStream : src, srcLen,
|
||||||
&props, dest + 1, &outPropsSize, 0,
|
&props, dest + 1, &outPropsSize, 0,
|
||||||
NULL, &g_Alloc, &g_Alloc);
|
NULL, &g_Alloc, &g_Alloc);
|
||||||
|
|
||||||
if (curRes != SZ_ERROR_OUTPUT_EOF)
|
if (curRes != SZ_ERROR_OUTPUT_EOF)
|
||||||
@@ -95,7 +95,7 @@ int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
|||||||
{
|
{
|
||||||
mainResult = curRes;
|
mainResult = curRes;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (outSizeProcessed <= minSize || mainResult != SZ_OK)
|
if (outSizeProcessed <= minSize || mainResult != SZ_OK)
|
||||||
{
|
{
|
||||||
minSize = outSizeProcessed;
|
minSize = outSizeProcessed;
|
||||||
|
|||||||
+10
-10
@@ -1,5 +1,5 @@
|
|||||||
/* Lzma86Enc.h -- LZMA + x86 (BCJ) Filter Encoder
|
/* Lzma86Enc.h -- LZMA + x86 (BCJ) Filter Encoder
|
||||||
2008-04-07
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ You can use .lzma86 extension, if you write that stream to file.
|
|||||||
.lzma86 header adds one additional byte to standard .lzma header.
|
.lzma86 header adds one additional byte to standard .lzma header.
|
||||||
.lzma86 header (14 bytes):
|
.lzma86 header (14 bytes):
|
||||||
Offset Size Description
|
Offset Size Description
|
||||||
0 1 = 0 - no filter,
|
0 1 = 0 - no filter,
|
||||||
= 1 - x86 filter
|
= 1 - x86 filter
|
||||||
1 1 lc, lp and pb in encoded form
|
1 1 lc, lp and pb in encoded form
|
||||||
2 4 dictSize (little endian)
|
2 4 dictSize (little endian)
|
||||||
@@ -26,25 +26,25 @@ Lzma86_Encode
|
|||||||
level - compression level: 0 <= level <= 9, the default value for "level" is 5.
|
level - compression level: 0 <= level <= 9, the default value for "level" is 5.
|
||||||
|
|
||||||
|
|
||||||
dictSize - The dictionary size in bytes. The maximum value is
|
dictSize - The dictionary size in bytes. The maximum value is
|
||||||
128 MB = (1 << 27) bytes for 32-bit version
|
128 MB = (1 << 27) bytes for 32-bit version
|
||||||
1 GB = (1 << 30) bytes for 64-bit version
|
1 GB = (1 << 30) bytes for 64-bit version
|
||||||
The default value is 16 MB = (1 << 24) bytes, for level = 5.
|
The default value is 16 MB = (1 << 24) bytes, for level = 5.
|
||||||
It's recommended to use the dictionary that is larger than 4 KB and
|
It's recommended to use the dictionary that is larger than 4 KB and
|
||||||
that can be calculated as (1 << N) or (3 << N) sizes.
|
that can be calculated as (1 << N) or (3 << N) sizes.
|
||||||
For better compression ratio dictSize must be >= inSize.
|
For better compression ratio dictSize must be >= inSize.
|
||||||
|
|
||||||
filterMode:
|
filterMode:
|
||||||
SZ_FILTER_NO - no Filter
|
SZ_FILTER_NO - no Filter
|
||||||
SZ_FILTER_YES - x86 Filter
|
SZ_FILTER_YES - x86 Filter
|
||||||
SZ_FILTER_AUTO - it tries both alternatives to select best.
|
SZ_FILTER_AUTO - it tries both alternatives to select best.
|
||||||
Encoder will use 2 or 3 passes:
|
Encoder will use 2 or 3 passes:
|
||||||
2 passes when FILTER_NO provides better compression.
|
2 passes when FILTER_NO provides better compression.
|
||||||
3 passes when FILTER_YES provides better compression.
|
3 passes when FILTER_YES provides better compression.
|
||||||
|
|
||||||
Lzma86Encode allocates Data with MyAlloc functions.
|
Lzma86Encode allocates Data with MyAlloc functions.
|
||||||
RAM Requirements for compressing:
|
RAM Requirements for compressing:
|
||||||
RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize
|
RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize
|
||||||
filterMode FilterBlockSize
|
filterMode FilterBlockSize
|
||||||
SZ_FILTER_NO 0
|
SZ_FILTER_NO 0
|
||||||
SZ_FILTER_YES inSize
|
SZ_FILTER_YES inSize
|
||||||
@@ -53,20 +53,20 @@ RAM Requirements for compressing:
|
|||||||
|
|
||||||
Return code:
|
Return code:
|
||||||
SZ_OK - OK
|
SZ_OK - OK
|
||||||
SZ_ERROR_MEM - Memory allocation error
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
SZ_ERROR_PARAM - Incorrect paramater
|
SZ_ERROR_PARAM - Incorrect paramater
|
||||||
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum ESzFilterMode
|
enum ESzFilterMode
|
||||||
{
|
{
|
||||||
SZ_FILTER_NO,
|
SZ_FILTER_NO,
|
||||||
SZ_FILTER_YES,
|
SZ_FILTER_YES,
|
||||||
SZ_FILTER_AUTO
|
SZ_FILTER_AUTO
|
||||||
};
|
};
|
||||||
|
|
||||||
SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
|
||||||
int level, UInt32 dictSize, int filterMode);
|
int level, UInt32 dictSize, int filterMode);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaUtil.c -- Test application for LZMA compression
|
/* LzmaUtil.c -- Test application for LZMA compression
|
||||||
2008-04-29
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
public domain */
|
public domain */
|
||||||
|
|
||||||
@@ -35,10 +35,10 @@ int MyReadFileAndCheck(FILE *file, void *data, size_t size)
|
|||||||
{ return (MyReadFile(file, data, size) == size); }
|
{ return (MyReadFile(file, data, size) == size); }
|
||||||
|
|
||||||
size_t MyWriteFile(FILE *file, const void *data, size_t size)
|
size_t MyWriteFile(FILE *file, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
return fwrite(data, 1, size, file);
|
return fwrite(data, 1, size, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MyWriteFileAndCheck(FILE *file, const void *data, size_t size)
|
int MyWriteFileAndCheck(FILE *file, const void *data, size_t size)
|
||||||
@@ -137,7 +137,7 @@ static int Decode(FILE *inFile, FILE *outFile, char *rs)
|
|||||||
finishMode = LZMA_FINISH_END;
|
finishMode = LZMA_FINISH_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = LzmaDec_DecodeToBuf(&state, outBuf + outPos, &outProcessed,
|
res = LzmaDec_DecodeToBuf(&state, outBuf + outPos, &outProcessed,
|
||||||
inBuf + inPos, &inProcessed, finishMode, &status);
|
inBuf + inPos, &inProcessed, finishMode, &status);
|
||||||
inPos += (UInt32)inProcessed;
|
inPos += (UInt32)inProcessed;
|
||||||
outPos += outProcessed;
|
outPos += outProcessed;
|
||||||
@@ -228,7 +228,7 @@ static SRes Encode(FILE *inFile, FILE *outFile, char *rs)
|
|||||||
return PrintError(rs, "writing error");
|
return PrintError(rs, "writing error");
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable,
|
res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable,
|
||||||
NULL, &g_Alloc, &g_Alloc);
|
NULL, &g_Alloc, &g_Alloc);
|
||||||
}
|
}
|
||||||
LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
|
LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
PROG = lzma
|
PROG = lzma
|
||||||
CXX = g++
|
CXX = g++
|
||||||
LIB =
|
LIB =
|
||||||
RM = rm -f
|
RM = rm -f
|
||||||
CFLAGS = -c -O2 -Wall
|
CFLAGS = -c -O2 -Wall
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
/* RotateDefs.h -- Rotate functions
|
/* RotateDefs.h -- Rotate functions
|
||||||
2008-03-24
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
#ifndef __ROTATEDEFS_H
|
#ifndef __ROTATEDEFS_H
|
||||||
|
|||||||
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
/* Crypto/Sha256.c -- SHA-256 Hash function
|
/* Crypto/Sha256.c -- SHA-256 Hash function
|
||||||
2008-03-24
|
2008-08-05
|
||||||
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.
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
#include "Sha256.h"
|
#include "Sha256.h"
|
||||||
@@ -151,7 +151,7 @@ static void Sha256_WriteByteBlock(CSha256 *p)
|
|||||||
UInt32 data32[16];
|
UInt32 data32[16];
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
data32[i] =
|
data32[i] =
|
||||||
((UInt32)(p->buffer[i * 4 ]) << 24) +
|
((UInt32)(p->buffer[i * 4 ]) << 24) +
|
||||||
((UInt32)(p->buffer[i * 4 + 1]) << 16) +
|
((UInt32)(p->buffer[i * 4 + 1]) << 16) +
|
||||||
((UInt32)(p->buffer[i * 4 + 2]) << 8) +
|
((UInt32)(p->buffer[i * 4 + 2]) << 8) +
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
/* Crypto/Sha256.h -- SHA-256 Hash function
|
/* Crypto/Sha256.h -- SHA-256 Hash function
|
||||||
2008-03-24
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
#ifndef __CRYPTO_SHA256_H
|
#ifndef __CRYPTO_SHA256_H
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ void HeapSort(UInt32 *p, UInt32 size)
|
|||||||
UInt32 temp = p[size];
|
UInt32 temp = p[size];
|
||||||
UInt32 k = (p[3] > p[2]) ? 3 : 2;
|
UInt32 k = (p[3] > p[2]) ? 3 : 2;
|
||||||
p[size--] = p[1];
|
p[size--] = p[1];
|
||||||
p[1] = p[k];
|
p[1] = p[k];
|
||||||
HeapSortDown(p, k, size, temp)
|
HeapSortDown(p, k, size, temp)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|||||||
+14
-14
@@ -1,5 +1,5 @@
|
|||||||
/* Threads.c -- multithreading library
|
/* Threads.c -- multithreading library
|
||||||
2008-04-04
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
@@ -25,9 +25,9 @@ static WRes MyCloseHandle(HANDLE *h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)
|
WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)
|
||||||
{
|
{
|
||||||
unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
|
unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
|
||||||
thread->handle =
|
thread->handle =
|
||||||
/* CreateThread(0, 0, startAddress, parameter, 0, &threadId); */
|
/* CreateThread(0, 0, startAddress, parameter, 0, &threadId); */
|
||||||
(HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, &threadId);
|
(HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, &threadId);
|
||||||
/* maybe we must use errno here, but probably GetLastError() is also OK. */
|
/* maybe we must use errno here, but probably GetLastError() is also OK. */
|
||||||
@@ -36,14 +36,14 @@ WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE
|
|||||||
|
|
||||||
WRes WaitObject(HANDLE h)
|
WRes WaitObject(HANDLE h)
|
||||||
{
|
{
|
||||||
return (WRes)WaitForSingleObject(h, INFINITE);
|
return (WRes)WaitForSingleObject(h, INFINITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
WRes Thread_Wait(CThread *thread)
|
WRes Thread_Wait(CThread *thread)
|
||||||
{
|
{
|
||||||
if (thread->handle == NULL)
|
if (thread->handle == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
return WaitObject(thread->handle);
|
return WaitObject(thread->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
WRes Thread_Close(CThread *thread)
|
WRes Thread_Close(CThread *thread)
|
||||||
@@ -59,12 +59,12 @@ WRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled)
|
|||||||
|
|
||||||
WRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled)
|
WRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled)
|
||||||
{ return Event_Create(p, TRUE, initialSignaled); }
|
{ return Event_Create(p, TRUE, initialSignaled); }
|
||||||
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p)
|
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p)
|
||||||
{ return ManualResetEvent_Create(p, 0); }
|
{ return ManualResetEvent_Create(p, 0); }
|
||||||
|
|
||||||
WRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled)
|
WRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled)
|
||||||
{ return Event_Create(p, FALSE, initialSignaled); }
|
{ return Event_Create(p, FALSE, initialSignaled); }
|
||||||
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p)
|
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p)
|
||||||
{ return AutoResetEvent_Create(p, 0); }
|
{ return AutoResetEvent_Create(p, 0); }
|
||||||
|
|
||||||
WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(p->handle)); }
|
WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(p->handle)); }
|
||||||
@@ -79,9 +79,9 @@ WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount)
|
|||||||
return HandleToWRes(p->handle);
|
return HandleToWRes(p->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
|
WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
|
||||||
{
|
{
|
||||||
return BOOLToWRes(ReleaseSemaphore(p->handle, releaseCount, previousCount));
|
return BOOLToWRes(ReleaseSemaphore(p->handle, releaseCount, previousCount));
|
||||||
}
|
}
|
||||||
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount)
|
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount)
|
||||||
{
|
{
|
||||||
@@ -98,11 +98,11 @@ WRes Semaphore_Close(CSemaphore *p) { return MyCloseHandle(&p->handle); }
|
|||||||
WRes CriticalSection_Init(CCriticalSection *p)
|
WRes CriticalSection_Init(CCriticalSection *p)
|
||||||
{
|
{
|
||||||
/* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
|
/* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
InitializeCriticalSection(p);
|
InitializeCriticalSection(p);
|
||||||
/* InitializeCriticalSectionAndSpinCount(p, 0); */
|
/* InitializeCriticalSectionAndSpinCount(p, 0); */
|
||||||
}
|
}
|
||||||
__except (EXCEPTION_EXECUTE_HANDLER) { return 1; }
|
__except (EXCEPTION_EXECUTE_HANDLER) { return 1; }
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Types.h -- Basic types
|
/* Types.h -- Basic types
|
||||||
2008-04-11
|
2008-08-05
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
@@ -83,8 +83,8 @@ typedef int Bool;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MY_CDECL __cdecl
|
#define MY_CDECL __cdecl
|
||||||
#define MY_STD_CALL __stdcall
|
#define MY_STD_CALL __stdcall
|
||||||
#define MY_FAST_CALL MY_NO_INLINE __fastcall
|
#define MY_FAST_CALL MY_NO_INLINE __fastcall
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|||||||
Executable
+640
@@ -0,0 +1,640 @@
|
|||||||
|
# Microsoft Developer Studio Project File - Name="7z" - Package Owner=<4>
|
||||||
|
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||||
|
# ** DO NOT EDIT **
|
||||||
|
|
||||||
|
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||||
|
|
||||||
|
CFG=7z - 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 "7z.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 "7z.mak" CFG="7z - Win32 Debug"
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE Possible choices for configuration are:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE "7z - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE "7z - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||||
|
!MESSAGE
|
||||||
|
|
||||||
|
# Begin Project
|
||||||
|
# PROP AllowPerConfigDependencies 0
|
||||||
|
# PROP Scc_ProjName ""
|
||||||
|
# PROP Scc_LocalPath ""
|
||||||
|
CPP=cl.exe
|
||||||
|
MTL=midl.exe
|
||||||
|
RSC=rc.exe
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "7z - 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 Ignore_Export_Lib 1
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /c
|
||||||
|
# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /D "EXTERNAL_CODECS" /Yu"StdAfx.h" /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 0x409 /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 /dll /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 /dll /machine:I386 /out:"C:\Program Files\7-zip\Formats\7z.dll" /opt:NOWIN98
|
||||||
|
# SUBTRACT LINK32 /pdb:none
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "7z - 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 1
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /YX /FD /GZ /c
|
||||||
|
# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MY7Z_EXPORTS" /D "COMPRESS_MT" /D "EXTERNAL_CODECS" /Yu"StdAfx.h" /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 0x409 /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 /dll /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 /dll /debug /machine:I386 /out:"C:\Program Files\7-zip\Formats\7z.dll" /pdbtype:sept
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Begin Target
|
||||||
|
|
||||||
|
# Name "7z - Win32 Release"
|
||||||
|
# Name "7z - Win32 Debug"
|
||||||
|
# Begin Group "Spec"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Archive.def
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\ArchiveExports.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\DllExports.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\resource.rc
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\StdAfx.cpp
|
||||||
|
# ADD CPP /Yc"StdAfx.h"
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\StdAfx.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Engine"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zCompressionMode.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zCompressionMode.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zDecode.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zDecode.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zEncode.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zEncode.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zExtract.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zFolderInStream.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zFolderInStream.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zFolderOutStream.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zFolderOutStream.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zHandler.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zHandler.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zHandlerOut.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zHeader.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zHeader.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zIn.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zIn.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zItem.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zOut.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zOut.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zProperties.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zProperties.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zRegister.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zSpecStream.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zSpecStream.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zUpdate.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\7zUpdate.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Interface"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\IArchive.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\ICoder.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\IMyUnknown.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\IPassword.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\IProgress.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\IStream.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\PropID.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Common"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\Buffer.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\CRC.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\DynamicBuffer.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\IntToString.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\IntToString.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\MyString.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\MyString.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\MyVector.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\MyVector.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\NewHandler.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\NewHandler.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\StringConvert.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\StringConvert.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\StringToInt.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Common\StringToInt.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Archive Common"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\CoderMixer2.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\CoderMixer2.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\CoderMixer2MT.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\CoderMixer2MT.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\CrossThreadProgress.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\CrossThreadProgress.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\HandlerOut.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\HandlerOut.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\InStreamWithCRC.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\InStreamWithCRC.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\ItemNameUtils.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\ItemNameUtils.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\MultiStream.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\MultiStream.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\OutStreamWithCRC.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\OutStreamWithCRC.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\ParseProperties.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\Common\ParseProperties.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "7-Zip Common"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\CreateCoder.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\CreateCoder.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\FilterCoder.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\FilterCoder.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\InOutTempBuffer.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\InOutTempBuffer.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\LimitedStreams.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\LimitedStreams.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\LockedStream.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\LockedStream.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\MethodId.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\MethodId.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\MethodProps.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\MethodProps.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\OutBuffer.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\OutBuffer.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\ProgressUtils.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\ProgressUtils.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\RegisterArc.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\RegisterCodec.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\StreamBinder.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\StreamBinder.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\StreamObjects.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\StreamObjects.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\StreamUtils.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\StreamUtils.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\VirtThread.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Common\VirtThread.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Windows"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\DLL.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\DLL.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\FileDir.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\FileDir.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\FileFind.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\FileFind.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\FileIO.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\FileIO.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\FileName.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\Handle.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\PropVariant.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\PropVariant.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\Synchronization.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\Synchronization.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\System.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\System.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\Windows\Thread.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Compress"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Copy\CopyCoder.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\Compress\Copy\CopyCoder.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "C"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\..\C\7zCrc.c
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\..\C\7zCrc.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\..\C\Alloc.c
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\..\C\Alloc.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\..\C\Threads.c
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\..\..\C\Threads.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# End Target
|
||||||
|
# End Project
|
||||||
Executable
+29
@@ -0,0 +1,29 @@
|
|||||||
|
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||||
|
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "7z"=".\7z.dsp" - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Global:
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<3>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ struct CCompressionMethodMode
|
|||||||
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
|
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
|
||||||
CCompressionMethodMode(): PasswordIsDefined(false)
|
CCompressionMethodMode(): PasswordIsDefined(false)
|
||||||
#ifdef COMPRESS_MT
|
#ifdef COMPRESS_MT
|
||||||
, NumThreads(1)
|
, NumThreads(1)
|
||||||
#endif
|
#endif
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ static void ConvertFolderItemInfoToBindInfo(const CFolder &folder,
|
|||||||
bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]);
|
bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1,
|
static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1,
|
||||||
const NCoderMixer::CCoderStreamsInfo &a2)
|
const NCoderMixer::CCoderStreamsInfo &a2)
|
||||||
{
|
{
|
||||||
return (a1.NumInStreams == a2.NumInStreams) &&
|
return (a1.NumInStreams == a2.NumInStreams) &&
|
||||||
@@ -94,17 +94,20 @@ HRESULT CDecoder::Decode(
|
|||||||
IInStream *inStream,
|
IInStream *inStream,
|
||||||
UInt64 startPos,
|
UInt64 startPos,
|
||||||
const UInt64 *packSizes,
|
const UInt64 *packSizes,
|
||||||
const CFolder &folderInfo,
|
const CFolder &folderInfo,
|
||||||
ISequentialOutStream *outStream,
|
ISequentialOutStream *outStream,
|
||||||
ICompressProgressInfo *compressProgress
|
ICompressProgressInfo *compressProgress
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, ICryptoGetTextPassword *getTextPassword
|
, ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
#ifdef COMPRESS_MT
|
#ifdef COMPRESS_MT
|
||||||
, bool mtMode, UInt32 numThreads
|
, bool mtMode, UInt32 numThreads
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
#ifndef _NO_CRYPTO
|
||||||
|
passwordIsDefined = false;
|
||||||
|
#endif
|
||||||
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
|
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
|
||||||
|
|
||||||
CLockedInStream lockedInStream;
|
CLockedInStream lockedInStream;
|
||||||
@@ -112,13 +115,13 @@ HRESULT CDecoder::Decode(
|
|||||||
|
|
||||||
for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
|
for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
|
||||||
{
|
{
|
||||||
CLockedSequentialInStreamImp *lockedStreamImpSpec = new
|
CLockedSequentialInStreamImp *lockedStreamImpSpec = new
|
||||||
CLockedSequentialInStreamImp;
|
CLockedSequentialInStreamImp;
|
||||||
CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
|
CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
|
||||||
lockedStreamImpSpec->Init(&lockedInStream, startPos);
|
lockedStreamImpSpec->Init(&lockedInStream, startPos);
|
||||||
startPos += packSizes[j];
|
startPos += packSizes[j];
|
||||||
|
|
||||||
CLimitedSequentialInStream *streamSpec = new
|
CLimitedSequentialInStream *streamSpec = new
|
||||||
CLimitedSequentialInStream;
|
CLimitedSequentialInStream;
|
||||||
CMyComPtr<ISequentialInStream> inStream = streamSpec;
|
CMyComPtr<ISequentialInStream> inStream = streamSpec;
|
||||||
streamSpec->SetStream(lockedStreamImp);
|
streamSpec->SetStream(lockedStreamImp);
|
||||||
@@ -212,7 +215,7 @@ HRESULT CDecoder::Decode(
|
|||||||
int i;
|
int i;
|
||||||
_mixerCoderCommon->ReInit();
|
_mixerCoderCommon->ReInit();
|
||||||
|
|
||||||
UInt32 packStreamIndex = 0, unPackStreamIndex = 0;
|
UInt32 packStreamIndex = 0, unpackStreamIndex = 0;
|
||||||
UInt32 coderIndex = 0;
|
UInt32 coderIndex = 0;
|
||||||
// UInt32 coder2Index = 0;
|
// UInt32 coder2Index = 0;
|
||||||
|
|
||||||
@@ -257,20 +260,20 @@ HRESULT CDecoder::Decode(
|
|||||||
{
|
{
|
||||||
if (getTextPassword == 0)
|
if (getTextPassword == 0)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
CMyComBSTR password;
|
CMyComBSTR passwordBSTR;
|
||||||
RINOK(getTextPassword->CryptoGetTextPassword(&password));
|
RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR));
|
||||||
CByteBuffer buffer;
|
CByteBuffer buffer;
|
||||||
UString unicodePassword(password);
|
passwordIsDefined = true;
|
||||||
const UInt32 sizeInBytes = unicodePassword.Length() * 2;
|
UString password = passwordBSTR;
|
||||||
|
const UInt32 sizeInBytes = password.Length() * 2;
|
||||||
buffer.SetCapacity(sizeInBytes);
|
buffer.SetCapacity(sizeInBytes);
|
||||||
for (int i = 0; i < unicodePassword.Length(); i++)
|
for (int i = 0; i < password.Length(); i++)
|
||||||
{
|
{
|
||||||
wchar_t c = unicodePassword[i];
|
wchar_t c = password[i];
|
||||||
((Byte *)buffer)[i * 2] = (Byte)c;
|
((Byte *)buffer)[i * 2] = (Byte)c;
|
||||||
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
||||||
}
|
}
|
||||||
RINOK(cryptoSetPassword->CryptoSetPassword(
|
RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
|
||||||
(const Byte *)buffer, sizeInBytes));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -280,19 +283,19 @@ HRESULT CDecoder::Decode(
|
|||||||
UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;
|
UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;
|
||||||
UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;
|
UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;
|
||||||
CRecordVector<const UInt64 *> packSizesPointers;
|
CRecordVector<const UInt64 *> packSizesPointers;
|
||||||
CRecordVector<const UInt64 *> unPackSizesPointers;
|
CRecordVector<const UInt64 *> unpackSizesPointers;
|
||||||
packSizesPointers.Reserve(numInStreams);
|
packSizesPointers.Reserve(numInStreams);
|
||||||
unPackSizesPointers.Reserve(numOutStreams);
|
unpackSizesPointers.Reserve(numOutStreams);
|
||||||
UInt32 j;
|
UInt32 j;
|
||||||
for (j = 0; j < numOutStreams; j++, unPackStreamIndex++)
|
for (j = 0; j < numOutStreams; j++, unpackStreamIndex++)
|
||||||
unPackSizesPointers.Add(&folderInfo.UnPackSizes[unPackStreamIndex]);
|
unpackSizesPointers.Add(&folderInfo.UnpackSizes[unpackStreamIndex]);
|
||||||
|
|
||||||
for (j = 0; j < numInStreams; j++, packStreamIndex++)
|
for (j = 0; j < numInStreams; j++, packStreamIndex++)
|
||||||
{
|
{
|
||||||
int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
|
int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
|
||||||
if (bindPairIndex >= 0)
|
if (bindPairIndex >= 0)
|
||||||
packSizesPointers.Add(
|
packSizesPointers.Add(
|
||||||
&folderInfo.UnPackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
|
&folderInfo.UnpackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
|
int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
|
||||||
@@ -302,9 +305,9 @@ HRESULT CDecoder::Decode(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_mixerCoderCommon->SetCoderInfo(i,
|
_mixerCoderCommon->SetCoderInfo(i,
|
||||||
&packSizesPointers.Front(),
|
&packSizesPointers.Front(),
|
||||||
&unPackSizesPointers.Front());
|
&unpackSizesPointers.Front());
|
||||||
}
|
}
|
||||||
UInt32 mainCoder, temp;
|
UInt32 mainCoder, temp;
|
||||||
bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
|
bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
|
||||||
@@ -323,7 +326,7 @@ HRESULT CDecoder::Decode(
|
|||||||
for (i = 0; i < inStreams.Size(); i++)
|
for (i = 0; i < inStreams.Size(); i++)
|
||||||
inStreamPointers.Add(inStreams[i]);
|
inStreamPointers.Add(inStreams[i]);
|
||||||
ISequentialOutStream *outStreamPointer = outStream;
|
ISequentialOutStream *outStreamPointer = outStream;
|
||||||
return _mixerCoder->Code(&inStreamPointers.Front(), NULL,
|
return _mixerCoder->Code(&inStreamPointers.Front(), NULL,
|
||||||
inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
|
inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,11 +51,11 @@ public:
|
|||||||
IInStream *inStream,
|
IInStream *inStream,
|
||||||
UInt64 startPos,
|
UInt64 startPos,
|
||||||
const UInt64 *packSizes,
|
const UInt64 *packSizes,
|
||||||
const CFolder &folder,
|
const CFolder &folder,
|
||||||
ISequentialOutStream *outStream,
|
ISequentialOutStream *outStream,
|
||||||
ICompressProgressInfo *compressProgress
|
ICompressProgressInfo *compressProgress
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, ICryptoGetTextPassword *getTextPasswordSpec
|
, ICryptoGetTextPassword *getTextPasswordSpec, bool &passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
#ifdef COMPRESS_MT
|
#ifdef COMPRESS_MT
|
||||||
, bool mtMode, UInt32 numThreads
|
, bool mtMode, UInt32 numThreads
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ HRESULT CEncoder::Encode(
|
|||||||
}
|
}
|
||||||
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
||||||
{
|
{
|
||||||
CSequentialOutTempBufferImp *tempBufferSpec =
|
CSequentialOutTempBufferImp *tempBufferSpec =
|
||||||
new CSequentialOutTempBufferImp;
|
new CSequentialOutTempBufferImp;
|
||||||
CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
|
CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
|
||||||
tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
|
tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
|
||||||
@@ -195,10 +195,10 @@ 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;
|
||||||
|
|
||||||
@@ -275,7 +275,7 @@ HRESULT CEncoder::Encode(
|
|||||||
streamSize = inStreamSizeCountSpec->GetSize();
|
streamSize = inStreamSizeCountSpec->GetSize();
|
||||||
else
|
else
|
||||||
streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
|
streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
|
||||||
folderItem.UnPackSizes.Add(streamSize);
|
folderItem.UnpackSizes.Add(streamSize);
|
||||||
}
|
}
|
||||||
for (i = numMethods - 1; i >= 0; i--)
|
for (i = numMethods - 1; i >= 0; i--)
|
||||||
folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties;
|
folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties;
|
||||||
|
|||||||
@@ -23,18 +23,18 @@ struct CExtractFolderInfo
|
|||||||
CNum FileIndex;
|
CNum FileIndex;
|
||||||
CNum FolderIndex;
|
CNum FolderIndex;
|
||||||
CBoolVector ExtractStatuses;
|
CBoolVector ExtractStatuses;
|
||||||
UInt64 UnPackSize;
|
UInt64 UnpackSize;
|
||||||
CExtractFolderInfo(
|
CExtractFolderInfo(
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
int volumeIndex,
|
int volumeIndex,
|
||||||
#endif
|
#endif
|
||||||
CNum fileIndex, CNum folderIndex):
|
CNum fileIndex, CNum folderIndex):
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
VolumeIndex(volumeIndex),
|
VolumeIndex(volumeIndex),
|
||||||
#endif
|
#endif
|
||||||
FileIndex(fileIndex),
|
FileIndex(fileIndex),
|
||||||
FolderIndex(folderIndex),
|
FolderIndex(folderIndex),
|
||||||
UnPackSize(0)
|
UnpackSize(0)
|
||||||
{
|
{
|
||||||
if (fileIndex != kNumNoIndex)
|
if (fileIndex != kNumNoIndex)
|
||||||
{
|
{
|
||||||
@@ -50,15 +50,15 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (testModeSpec != 0);
|
bool testMode = (testModeSpec != 0);
|
||||||
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
||||||
UInt64 importantTotalUnPacked = 0;
|
UInt64 importantTotalUnpacked = 0;
|
||||||
|
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
bool allFilesMode = (numItems == UInt32(-1));
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems =
|
numItems =
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
_refs.Size();
|
_refs.Size();
|
||||||
#else
|
#else
|
||||||
_database.Files.Size();
|
_db.Files.Size();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(numItems == 0)
|
if(numItems == 0)
|
||||||
@@ -68,7 +68,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
if(_volumes.Size() != 1)
|
if(_volumes.Size() != 1)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
const CVolume &volume = _volumes.Front();
|
const CVolume &volume = _volumes.Front();
|
||||||
const CArchiveDatabaseEx &_database = volume.Database;
|
const CArchiveDatabaseEx &_db = volume.Database;
|
||||||
IInStream *_inStream = volume.Stream;
|
IInStream *_inStream = volume.Stream;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -87,25 +87,25 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
|
|
||||||
int volumeIndex = ref.VolumeIndex;
|
int volumeIndex = ref.VolumeIndex;
|
||||||
const CVolume &volume = _volumes[volumeIndex];
|
const CVolume &volume = _volumes[volumeIndex];
|
||||||
const CArchiveDatabaseEx &database = volume.Database;
|
const CArchiveDatabaseEx &db = volume.Database;
|
||||||
UInt32 fileIndex = ref.ItemIndex;
|
UInt32 fileIndex = ref.ItemIndex;
|
||||||
#else
|
#else
|
||||||
const CArchiveDatabaseEx &database = _database;
|
const CArchiveDatabaseEx &db = _db;
|
||||||
UInt32 fileIndex = ref2Index;
|
UInt32 fileIndex = ref2Index;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CNum folderIndex = database.FileIndexToFolderIndexMap[fileIndex];
|
CNum folderIndex = db.FileIndexToFolderIndexMap[fileIndex];
|
||||||
if (folderIndex == kNumNoIndex)
|
if (folderIndex == kNumNoIndex)
|
||||||
{
|
{
|
||||||
extractFolderInfoVector.Add(CExtractFolderInfo(
|
extractFolderInfoVector.Add(CExtractFolderInfo(
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
volumeIndex,
|
volumeIndex,
|
||||||
#endif
|
#endif
|
||||||
fileIndex, kNumNoIndex));
|
fileIndex, kNumNoIndex));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (extractFolderInfoVector.IsEmpty() ||
|
if (extractFolderInfoVector.IsEmpty() ||
|
||||||
folderIndex != extractFolderInfoVector.Back().FolderIndex
|
folderIndex != extractFolderInfoVector.Back().FolderIndex
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
|| volumeIndex != extractFolderInfoVector.Back().VolumeIndex
|
|| volumeIndex != extractFolderInfoVector.Back().VolumeIndex
|
||||||
#endif
|
#endif
|
||||||
@@ -113,32 +113,32 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
{
|
{
|
||||||
extractFolderInfoVector.Add(CExtractFolderInfo(
|
extractFolderInfoVector.Add(CExtractFolderInfo(
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
volumeIndex,
|
volumeIndex,
|
||||||
#endif
|
#endif
|
||||||
kNumNoIndex, folderIndex));
|
kNumNoIndex, folderIndex));
|
||||||
const CFolder &folderInfo = database.Folders[folderIndex];
|
const CFolder &folderInfo = db.Folders[folderIndex];
|
||||||
UInt64 unPackSize = folderInfo.GetUnPackSize();
|
UInt64 unpackSize = folderInfo.GetUnpackSize();
|
||||||
importantTotalUnPacked += unPackSize;
|
importantTotalUnpacked += unpackSize;
|
||||||
extractFolderInfoVector.Back().UnPackSize = unPackSize;
|
extractFolderInfoVector.Back().UnpackSize = unpackSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
CExtractFolderInfo &efi = extractFolderInfoVector.Back();
|
CExtractFolderInfo &efi = extractFolderInfoVector.Back();
|
||||||
|
|
||||||
// const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
|
// const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
|
||||||
CNum startIndex = database.FolderStartFileIndex[folderIndex];
|
CNum startIndex = db.FolderStartFileIndex[folderIndex];
|
||||||
for (CNum index = efi.ExtractStatuses.Size();
|
for (CNum index = efi.ExtractStatuses.Size();
|
||||||
index <= fileIndex - startIndex; index++)
|
index <= fileIndex - startIndex; index++)
|
||||||
{
|
{
|
||||||
// UInt64 unPackSize = _database.Files[startIndex + index].UnPackSize;
|
// UInt64 unpackSize = _db.Files[startIndex + index].UnpackSize;
|
||||||
// Count partial_folder_size
|
// Count partial_folder_size
|
||||||
// efi.UnPackSize += unPackSize;
|
// efi.UnpackSize += unpackSize;
|
||||||
// importantTotalUnPacked += unPackSize;
|
// importantTotalUnpacked += unpackSize;
|
||||||
efi.ExtractStatuses.Add(index == fileIndex - startIndex);
|
efi.ExtractStatuses.Add(index == fileIndex - startIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extractCallback->SetTotal(importantTotalUnPacked);
|
extractCallback->SetTotal(importantTotalUnpacked);
|
||||||
|
|
||||||
CDecoder decoder(
|
CDecoder decoder(
|
||||||
#ifdef _ST_MODE
|
#ifdef _ST_MODE
|
||||||
@@ -150,24 +150,24 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
// CDecoder1 decoder;
|
// CDecoder1 decoder;
|
||||||
|
|
||||||
UInt64 currentTotalPacked = 0;
|
UInt64 currentTotalPacked = 0;
|
||||||
UInt64 currentTotalUnPacked = 0;
|
UInt64 currentTotalUnpacked = 0;
|
||||||
UInt64 totalFolderUnPacked;
|
UInt64 totalFolderUnpacked;
|
||||||
UInt64 totalFolderPacked;
|
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 < extractFolderInfoVector.Size(); i++,
|
||||||
currentTotalUnPacked += totalFolderUnPacked,
|
currentTotalUnpacked += totalFolderUnpacked,
|
||||||
currentTotalPacked += totalFolderPacked)
|
currentTotalPacked += totalFolderPacked)
|
||||||
{
|
{
|
||||||
lps->OutSize = currentTotalUnPacked;
|
lps->OutSize = currentTotalUnpacked;
|
||||||
lps->InSize = currentTotalPacked;
|
lps->InSize = currentTotalPacked;
|
||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
|
|
||||||
const CExtractFolderInfo &efi = extractFolderInfoVector[i];
|
const CExtractFolderInfo &efi = extractFolderInfoVector[i];
|
||||||
totalFolderUnPacked = efi.UnPackSize;
|
totalFolderUnpacked = efi.UnpackSize;
|
||||||
|
|
||||||
totalFolderPacked = 0;
|
totalFolderPacked = 0;
|
||||||
|
|
||||||
@@ -176,25 +176,25 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
|
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
const CVolume &volume = _volumes[efi.VolumeIndex];
|
const CVolume &volume = _volumes[efi.VolumeIndex];
|
||||||
const CArchiveDatabaseEx &database = volume.Database;
|
const CArchiveDatabaseEx &db = volume.Database;
|
||||||
#else
|
#else
|
||||||
const CArchiveDatabaseEx &database = _database;
|
const CArchiveDatabaseEx &db = _db;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CNum startIndex;
|
CNum startIndex;
|
||||||
if (efi.FileIndex != kNumNoIndex)
|
if (efi.FileIndex != kNumNoIndex)
|
||||||
startIndex = efi.FileIndex;
|
startIndex = efi.FileIndex;
|
||||||
else
|
else
|
||||||
startIndex = database.FolderStartFileIndex[efi.FolderIndex];
|
startIndex = db.FolderStartFileIndex[efi.FolderIndex];
|
||||||
|
|
||||||
|
|
||||||
HRESULT result = folderOutStream->Init(&database,
|
HRESULT result = folderOutStream->Init(&db,
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
volume.StartRef2Index,
|
volume.StartRef2Index,
|
||||||
#else
|
#else
|
||||||
0,
|
0,
|
||||||
#endif
|
#endif
|
||||||
startIndex,
|
startIndex,
|
||||||
&efi.ExtractStatuses, extractCallback, testMode, _crcSize != 0);
|
&efi.ExtractStatuses, extractCallback, testMode, _crcSize != 0);
|
||||||
|
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
@@ -203,12 +203,12 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
CNum folderIndex = efi.FolderIndex;
|
CNum folderIndex = efi.FolderIndex;
|
||||||
const CFolder &folderInfo = database.Folders[folderIndex];
|
const CFolder &folderInfo = db.Folders[folderIndex];
|
||||||
|
|
||||||
totalFolderPacked = _database.GetFolderFullPackSize(folderIndex);
|
totalFolderPacked = _db.GetFolderFullPackSize(folderIndex);
|
||||||
|
|
||||||
CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex];
|
CNum packStreamIndex = db.FolderStartPackStreamIndex[folderIndex];
|
||||||
UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0);
|
UInt64 folderStartPackPos = db.GetFolderStreamPos(folderIndex, 0);
|
||||||
|
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
||||||
@@ -218,6 +218,10 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
#ifndef _NO_CRYPTO
|
||||||
|
bool passwordIsDefined;
|
||||||
|
#endif
|
||||||
|
|
||||||
HRESULT result = decoder.Decode(
|
HRESULT result = decoder.Decode(
|
||||||
EXTERNAL_CODECS_VARS
|
EXTERNAL_CODECS_VARS
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
@@ -225,13 +229,13 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
#else
|
#else
|
||||||
_inStream,
|
_inStream,
|
||||||
#endif
|
#endif
|
||||||
folderStartPackPos,
|
folderStartPackPos,
|
||||||
&database.PackSizes[packStreamIndex],
|
&db.PackSizes[packStreamIndex],
|
||||||
folderInfo,
|
folderInfo,
|
||||||
outStream,
|
outStream,
|
||||||
progress
|
progress
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, getTextPassword
|
, getTextPassword, passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
#ifdef COMPRESS_MT
|
#ifdef COMPRESS_MT
|
||||||
, true, _numThreads
|
, true, _numThreads
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ CFolderInStream::CFolderInStream()
|
|||||||
_inStreamWithHash = _inStreamWithHashSpec;
|
_inStreamWithHash = _inStreamWithHashSpec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
|
void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
|
||||||
const UInt32 *fileIndices, UInt32 numFiles)
|
const UInt32 *fileIndices, UInt32 numFiles)
|
||||||
{
|
{
|
||||||
_updateCallback = updateCallback;
|
_updateCallback = updateCallback;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
class CFolderInStream:
|
class CFolderInStream:
|
||||||
public ISequentialInStream,
|
public ISequentialInStream,
|
||||||
public ICompressGetSubStreamSize,
|
public ICompressGetSubStreamSize,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
@@ -47,7 +47,7 @@ private:
|
|||||||
HRESULT CloseStream();
|
HRESULT CloseStream();
|
||||||
void AddDigest();
|
void AddDigest();
|
||||||
public:
|
public:
|
||||||
void Init(IArchiveUpdateCallback *updateCallback,
|
void Init(IArchiveUpdateCallback *updateCallback,
|
||||||
const UInt32 *fileIndices, UInt32 numFiles);
|
const UInt32 *fileIndices, UInt32 numFiles);
|
||||||
CRecordVector<bool> Processed;
|
CRecordVector<bool> Processed;
|
||||||
CRecordVector<UInt32> CRCs;
|
CRecordVector<UInt32> CRCs;
|
||||||
@@ -55,7 +55,7 @@ public:
|
|||||||
UInt64 GetFullSize() const
|
UInt64 GetFullSize() const
|
||||||
{
|
{
|
||||||
UInt64 size = 0;
|
UInt64 size = 0;
|
||||||
for (int i = 0; i < Sizes.Size(); i++)
|
for (int i = 0; i < Sizes.Size(); i++)
|
||||||
size += Sizes[i];
|
size += Sizes[i];
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ HRESULT CFolderOutStream::Init(
|
|||||||
const CArchiveDatabaseEx *archiveDatabase,
|
const CArchiveDatabaseEx *archiveDatabase,
|
||||||
UInt32 ref2Offset,
|
UInt32 ref2Offset,
|
||||||
UInt32 startIndex,
|
UInt32 startIndex,
|
||||||
const CBoolVector *extractStatuses,
|
const CBoolVector *extractStatuses,
|
||||||
IArchiveExtractCallback *extractCallback,
|
IArchiveExtractCallback *extractCallback,
|
||||||
bool testMode,
|
bool testMode,
|
||||||
bool checkCrc)
|
bool checkCrc)
|
||||||
@@ -41,7 +41,7 @@ HRESULT CFolderOutStream::OpenFile()
|
|||||||
{
|
{
|
||||||
Int32 askMode;
|
Int32 askMode;
|
||||||
if((*_extractStatuses)[_currentIndex])
|
if((*_extractStatuses)[_currentIndex])
|
||||||
askMode = _testMode ?
|
askMode = _testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NArchive::NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NArchive::NExtract::NAskMode::kExtract;
|
||||||
else
|
else
|
||||||
@@ -54,10 +54,10 @@ HRESULT CFolderOutStream::OpenFile()
|
|||||||
_outStreamWithHashSpec->SetStream(realOutStream);
|
_outStreamWithHashSpec->SetStream(realOutStream);
|
||||||
_outStreamWithHashSpec->Init(_checkCrc);
|
_outStreamWithHashSpec->Init(_checkCrc);
|
||||||
if (askMode == NArchive::NExtract::NAskMode::kExtract &&
|
if (askMode == NArchive::NExtract::NAskMode::kExtract &&
|
||||||
(!realOutStream))
|
(!realOutStream))
|
||||||
{
|
{
|
||||||
const CFileItem &fileInfo = _archiveDatabase->Files[index];
|
const CFileItem &fi = _archiveDatabase->Files[index];
|
||||||
if (!fileInfo.IsAnti && !fileInfo.IsDirectory)
|
if (!_archiveDatabase->IsItemAnti(index) && !fi.IsDir)
|
||||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||||
}
|
}
|
||||||
return _extractCallback->PrepareOperation(askMode);
|
return _extractCallback->PrepareOperation(askMode);
|
||||||
@@ -68,18 +68,17 @@ HRESULT CFolderOutStream::WriteEmptyFiles()
|
|||||||
for(;_currentIndex < _extractStatuses->Size(); _currentIndex++)
|
for(;_currentIndex < _extractStatuses->Size(); _currentIndex++)
|
||||||
{
|
{
|
||||||
UInt32 index = _startIndex + _currentIndex;
|
UInt32 index = _startIndex + _currentIndex;
|
||||||
const CFileItem &fileInfo = _archiveDatabase->Files[index];
|
const CFileItem &fi = _archiveDatabase->Files[index];
|
||||||
if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 0)
|
if (!_archiveDatabase->IsItemAnti(index) && !fi.IsDir && fi.Size != 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
RINOK(OpenFile());
|
RINOK(OpenFile());
|
||||||
RINOK(_extractCallback->SetOperationResult(
|
RINOK(_extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||||
NArchive::NExtract::NOperationResult::kOK));
|
|
||||||
_outStreamWithHashSpec->ReleaseStream();
|
_outStreamWithHashSpec->ReleaseStream();
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CFolderOutStream::Write(const void *data,
|
STDMETHODIMP CFolderOutStream::Write(const void *data,
|
||||||
UInt32 size, UInt32 *processedSize)
|
UInt32 size, UInt32 *processedSize)
|
||||||
{
|
{
|
||||||
UInt32 realProcessedSize = 0;
|
UInt32 realProcessedSize = 0;
|
||||||
@@ -88,14 +87,14 @@ STDMETHODIMP CFolderOutStream::Write(const void *data,
|
|||||||
if (_fileIsOpen)
|
if (_fileIsOpen)
|
||||||
{
|
{
|
||||||
UInt32 index = _startIndex + _currentIndex;
|
UInt32 index = _startIndex + _currentIndex;
|
||||||
const CFileItem &fileInfo = _archiveDatabase->Files[index];
|
const CFileItem &fi = _archiveDatabase->Files[index];
|
||||||
UInt64 fileSize = fileInfo.UnPackSize;
|
UInt64 fileSize = fi.Size;
|
||||||
|
|
||||||
UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos,
|
UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos,
|
||||||
UInt64(size - realProcessedSize));
|
UInt64(size - realProcessedSize));
|
||||||
|
|
||||||
UInt32 processedSizeLocal;
|
UInt32 processedSizeLocal;
|
||||||
RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize,
|
RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize,
|
||||||
numBytesToWrite, &processedSizeLocal));
|
numBytesToWrite, &processedSizeLocal));
|
||||||
|
|
||||||
_filePos += processedSizeLocal;
|
_filePos += processedSizeLocal;
|
||||||
@@ -103,13 +102,13 @@ STDMETHODIMP CFolderOutStream::Write(const void *data,
|
|||||||
if (_filePos == fileSize)
|
if (_filePos == fileSize)
|
||||||
{
|
{
|
||||||
bool digestsAreEqual;
|
bool digestsAreEqual;
|
||||||
if (fileInfo.IsFileCRCDefined && _checkCrc)
|
if (fi.CrcDefined && _checkCrc)
|
||||||
digestsAreEqual = fileInfo.FileCRC == _outStreamWithHashSpec->GetCRC();
|
digestsAreEqual = fi.Crc == _outStreamWithHashSpec->GetCRC();
|
||||||
else
|
else
|
||||||
digestsAreEqual = true;
|
digestsAreEqual = true;
|
||||||
|
|
||||||
RINOK(_extractCallback->SetOperationResult(
|
RINOK(_extractCallback->SetOperationResult(
|
||||||
digestsAreEqual ?
|
digestsAreEqual ?
|
||||||
NArchive::NExtract::NOperationResult::kOK :
|
NArchive::NExtract::NOperationResult::kOK :
|
||||||
NArchive::NExtract::NOperationResult::kCRCError));
|
NArchive::NExtract::NOperationResult::kCRCError));
|
||||||
_outStreamWithHashSpec->ReleaseStream();
|
_outStreamWithHashSpec->ReleaseStream();
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
class CFolderOutStream:
|
class CFolderOutStream:
|
||||||
public ISequentialOutStream,
|
public ISequentialOutStream,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
@@ -47,7 +47,7 @@ public:
|
|||||||
const CArchiveDatabaseEx *archiveDatabase,
|
const CArchiveDatabaseEx *archiveDatabase,
|
||||||
UInt32 ref2Offset,
|
UInt32 ref2Offset,
|
||||||
UInt32 startIndex,
|
UInt32 startIndex,
|
||||||
const CBoolVector *extractStatuses,
|
const CBoolVector *extractStatuses,
|
||||||
IArchiveExtractCallback *extractCallback,
|
IArchiveExtractCallback *extractCallback,
|
||||||
bool testMode,
|
bool testMode,
|
||||||
bool checkCrc);
|
bool checkCrc);
|
||||||
|
|||||||
@@ -10,9 +10,6 @@
|
|||||||
#include "../../../Windows/Defs.h"
|
#include "../../../Windows/Defs.h"
|
||||||
|
|
||||||
#include "../Common/ItemNameUtils.h"
|
#include "../Common/ItemNameUtils.h"
|
||||||
#ifdef _7Z_VOL
|
|
||||||
#include "../Common/MultiStream.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __7Z_SET_PROPERTIES
|
#ifdef __7Z_SET_PROPERTIES
|
||||||
#ifdef EXTRACT_ONLY
|
#ifdef EXTRACT_ONLY
|
||||||
@@ -35,9 +32,13 @@ CHandler::CHandler()
|
|||||||
{
|
{
|
||||||
_crcSize = 4;
|
_crcSize = 4;
|
||||||
|
|
||||||
|
#ifndef _NO_CRYPTO
|
||||||
|
_passwordIsDefined = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef EXTRACT_ONLY
|
#ifdef EXTRACT_ONLY
|
||||||
#ifdef COMPRESS_MT
|
#ifdef COMPRESS_MT
|
||||||
_numThreads = NWindows::NSystem::GetNumberOfProcessors();
|
_numThreads = NSystem::GetNumberOfProcessors();
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
Init();
|
Init();
|
||||||
@@ -46,12 +47,7 @@ CHandler::CHandler()
|
|||||||
|
|
||||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||||
{
|
{
|
||||||
*numItems =
|
*numItems = _db.Files.Size();
|
||||||
#ifdef _7Z_VOL
|
|
||||||
_refs.Size();
|
|
||||||
#else
|
|
||||||
*numItems = _database.Files.Size();
|
|
||||||
#endif
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +60,7 @@ STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */)
|
|||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
|
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
|
||||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||||
{
|
{
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
@@ -73,17 +69,20 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
STATPROPSTG kArcProps[] =
|
STATPROPSTG kArcProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidMethod, VT_BSTR},
|
{ NULL, kpidMethod, VT_BSTR},
|
||||||
{ NULL, kpidSolid, VT_BOOL},
|
{ NULL, kpidSolid, VT_BOOL},
|
||||||
{ NULL, kpidNumBlocks, VT_UI4}
|
{ NULL, kpidNumBlocks, VT_UI4},
|
||||||
|
{ NULL, kpidPhySize, VT_UI8},
|
||||||
|
{ NULL, kpidHeadersSize, VT_UI8},
|
||||||
|
{ NULL, kpidOffset, VT_UI8}
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
NWindows::NCOM::CPropVariant prop;
|
NCOM::CPropVariant prop;
|
||||||
switch(propID)
|
switch(propID)
|
||||||
{
|
{
|
||||||
case kpidMethod:
|
case kpidMethod:
|
||||||
@@ -91,9 +90,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
UString resString;
|
UString resString;
|
||||||
CRecordVector<UInt64> ids;
|
CRecordVector<UInt64> ids;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < _database.Folders.Size(); i++)
|
for (i = 0; i < _db.Folders.Size(); i++)
|
||||||
{
|
{
|
||||||
const CFolder &f = _database.Folders[i];
|
const CFolder &f = _db.Folders[i];
|
||||||
for (int j = f.Coders.Size() - 1; j >= 0; j--)
|
for (int j = f.Coders.Size() - 1; j >= 0; j--)
|
||||||
ids.AddToUniqueSorted(f.Coders[j].MethodID);
|
ids.AddToUniqueSorted(f.Coders[j].MethodID);
|
||||||
}
|
}
|
||||||
@@ -109,11 +108,14 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
resString += L' ';
|
resString += L' ';
|
||||||
resString += methodName;
|
resString += methodName;
|
||||||
}
|
}
|
||||||
prop = resString;
|
prop = resString;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kpidSolid: prop = _database.IsSolid(); break;
|
case kpidSolid: prop = _db.IsSolid(); break;
|
||||||
case kpidNumBlocks: prop = (UInt32)_database.Folders.Size(); break;
|
case kpidNumBlocks: prop = (UInt32)_db.Folders.Size(); break;
|
||||||
|
case kpidHeadersSize: prop = _db.HeadersSize; break;
|
||||||
|
case kpidPhySize: prop = _db.PhySize; break;
|
||||||
|
case kpidOffset: if (_db.ArchiveInfo.StartPosition != 0) prop = _db.ArchiveInfo.StartPosition; break;
|
||||||
}
|
}
|
||||||
prop.Detach(value);
|
prop.Detach(value);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@@ -124,10 +126,16 @@ IMP_IInArchive_ArcProps
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void MySetFileTime(bool timeDefined, FILETIME unixTime, NWindows::NCOM::CPropVariant &prop)
|
static void SetPropFromUInt64Def(CUInt64DefVector &v, int index, NCOM::CPropVariant &prop)
|
||||||
{
|
{
|
||||||
if (timeDefined)
|
UInt64 value;
|
||||||
prop = unixTime;
|
if (v.GetItem(index, value))
|
||||||
|
{
|
||||||
|
FILETIME ft;
|
||||||
|
ft.dwLowDateTime = (DWORD)value;
|
||||||
|
ft.dwHighDateTime = (DWORD)(value >> 32);
|
||||||
|
prop = ft;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _SFX
|
#ifndef _SFX
|
||||||
@@ -192,10 +200,10 @@ static inline UInt32 GetUInt32FromMemLE(const Byte *p)
|
|||||||
|
|
||||||
bool CHandler::IsEncrypted(UInt32 index2) const
|
bool CHandler::IsEncrypted(UInt32 index2) const
|
||||||
{
|
{
|
||||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
||||||
if (folderIndex != kNumNoIndex)
|
if (folderIndex != kNumNoIndex)
|
||||||
{
|
{
|
||||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
const CFolder &folderInfo = _db.Folders[folderIndex];
|
||||||
for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
|
for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
|
||||||
if (folderInfo.Coders[i].MethodID == k_AES)
|
if (folderInfo.Coders[i].MethodID == k_AES)
|
||||||
return true;
|
return true;
|
||||||
@@ -206,7 +214,7 @@ bool CHandler::IsEncrypted(UInt32 index2) const
|
|||||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
NWindows::NCOM::CPropVariant prop;
|
NCOM::CPropVariant prop;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
const CRef2 &ref2 = _refs[index];
|
const CRef2 &ref2 = _refs[index];
|
||||||
@@ -215,54 +223,31 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
const CRef &ref = ref2.Refs.Front();
|
const CRef &ref = ref2.Refs.Front();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
const CFileItem &item = _db.Files[index];
|
||||||
const CRef &ref = _refs[index];
|
|
||||||
const CVolume &volume = _volumes[ref.VolumeIndex];
|
|
||||||
const CArchiveDatabaseEx &_database = volume.Database;
|
|
||||||
UInt32 index2 = ref.ItemIndex;
|
|
||||||
const CFileItem &item = _database.Files[index2];
|
|
||||||
#else
|
|
||||||
const CFileItem &item = _database.Files[index];
|
|
||||||
UInt32 index2 = index;
|
UInt32 index2 = index;
|
||||||
#endif
|
|
||||||
|
|
||||||
switch(propID)
|
switch(propID)
|
||||||
{
|
{
|
||||||
case kpidPath:
|
case kpidPath:
|
||||||
{
|
|
||||||
if (!item.Name.IsEmpty())
|
if (!item.Name.IsEmpty())
|
||||||
prop = NItemName::GetOSName(item.Name);
|
prop = NItemName::GetOSName(item.Name);
|
||||||
break;
|
break;
|
||||||
}
|
case kpidIsDir: prop = item.IsDir; break;
|
||||||
case kpidIsFolder:
|
|
||||||
prop = item.IsDirectory;
|
|
||||||
break;
|
|
||||||
case kpidSize:
|
case kpidSize:
|
||||||
{
|
{
|
||||||
prop = item.UnPackSize;
|
prop = item.Size;
|
||||||
// prop = ref2.UnPackSize;
|
// prop = ref2.Size;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kpidPosition:
|
case kpidPackSize:
|
||||||
{
|
|
||||||
/*
|
|
||||||
if (ref2.Refs.Size() > 1)
|
|
||||||
prop = ref2.StartPos;
|
|
||||||
else
|
|
||||||
*/
|
|
||||||
if (item.IsStartPosDefined)
|
|
||||||
prop = item.StartPos;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case kpidPackedSize:
|
|
||||||
{
|
{
|
||||||
// prop = ref2.PackSize;
|
// prop = ref2.PackSize;
|
||||||
{
|
{
|
||||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
||||||
if (folderIndex != kNumNoIndex)
|
if (folderIndex != kNumNoIndex)
|
||||||
{
|
{
|
||||||
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)
|
if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2)
|
||||||
prop = _database.GetFolderFullPackSize(folderIndex);
|
prop = _db.GetFolderFullPackSize(folderIndex);
|
||||||
/*
|
/*
|
||||||
else
|
else
|
||||||
prop = (UInt64)0;
|
prop = (UInt64)0;
|
||||||
@@ -273,35 +258,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kpidLastAccessTime:
|
case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) prop = v; break; }
|
||||||
MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, prop);
|
case kpidCTime: SetPropFromUInt64Def(_db.CTime, index2, prop); break;
|
||||||
break;
|
case kpidATime: SetPropFromUInt64Def(_db.ATime, index2, prop); break;
|
||||||
case kpidCreationTime:
|
case kpidMTime: SetPropFromUInt64Def(_db.MTime, index2, prop); break;
|
||||||
MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, prop);
|
case kpidAttrib: if (item.AttribDefined) prop = item.Attrib; break;
|
||||||
break;
|
case kpidCRC: if (item.CrcDefined) prop = item.Crc; break;
|
||||||
case kpidLastWriteTime:
|
case kpidEncrypted: prop = IsEncrypted(index2); break;
|
||||||
MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, prop);
|
case kpidIsAnti: prop = _db.IsItemAnti(index2); break;
|
||||||
break;
|
|
||||||
case kpidAttributes:
|
|
||||||
if (item.AreAttributesDefined)
|
|
||||||
prop = item.Attributes;
|
|
||||||
break;
|
|
||||||
case kpidCRC:
|
|
||||||
if (item.IsFileCRCDefined)
|
|
||||||
prop = item.FileCRC;
|
|
||||||
break;
|
|
||||||
case kpidEncrypted:
|
|
||||||
{
|
|
||||||
prop = IsEncrypted(index2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#ifndef _SFX
|
#ifndef _SFX
|
||||||
case kpidMethod:
|
case kpidMethod:
|
||||||
{
|
{
|
||||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
||||||
if (folderIndex != kNumNoIndex)
|
if (folderIndex != kNumNoIndex)
|
||||||
{
|
{
|
||||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
const CFolder &folderInfo = _db.Folders[folderIndex];
|
||||||
UString methodsString;
|
UString methodsString;
|
||||||
for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
|
for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
@@ -312,7 +283,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
{
|
{
|
||||||
UString methodName;
|
UString methodName;
|
||||||
bool methodIsKnown = FindMethod(
|
bool methodIsKnown = FindMethod(
|
||||||
EXTERNAL_CODECS_VARS
|
EXTERNAL_CODECS_VARS
|
||||||
coderInfo.MethodID, methodName);
|
coderInfo.MethodID, methodName);
|
||||||
|
|
||||||
if (methodIsKnown)
|
if (methodIsKnown)
|
||||||
@@ -398,7 +369,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
break;
|
break;
|
||||||
case kpidBlock:
|
case kpidBlock:
|
||||||
{
|
{
|
||||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
||||||
if (folderIndex != kNumNoIndex)
|
if (folderIndex != kNumNoIndex)
|
||||||
prop = (UInt32)folderIndex;
|
prop = (UInt32)folderIndex;
|
||||||
}
|
}
|
||||||
@@ -409,14 +380,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
case kpidPackedSize3:
|
case kpidPackedSize3:
|
||||||
case kpidPackedSize4:
|
case kpidPackedSize4:
|
||||||
{
|
{
|
||||||
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
|
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
||||||
if (folderIndex != kNumNoIndex)
|
if (folderIndex != kNumNoIndex)
|
||||||
{
|
{
|
||||||
const CFolder &folderInfo = _database.Folders[folderIndex];
|
const CFolder &folderInfo = _db.Folders[folderIndex];
|
||||||
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
|
if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
|
||||||
folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
|
folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
|
||||||
{
|
{
|
||||||
prop = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
|
prop = _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
prop = (UInt64)0;
|
prop = (UInt64)0;
|
||||||
@@ -426,97 +397,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case kpidIsAnti:
|
|
||||||
prop = item.IsAnti;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
prop.Detach(value);
|
prop.Detach(value);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
|
|
||||||
static const wchar_t *kExt = L"7z";
|
|
||||||
static const wchar_t *kAfterPart = L".7z";
|
|
||||||
|
|
||||||
class CVolumeName
|
|
||||||
{
|
|
||||||
bool _first;
|
|
||||||
UString _unchangedPart;
|
|
||||||
UString _changedPart;
|
|
||||||
UString _afterPart;
|
|
||||||
public:
|
|
||||||
bool InitName(const UString &name)
|
|
||||||
{
|
|
||||||
_first = true;
|
|
||||||
int dotPos = name.ReverseFind('.');
|
|
||||||
UString basePart = name;
|
|
||||||
if (dotPos >= 0)
|
|
||||||
{
|
|
||||||
UString ext = name.Mid(dotPos + 1);
|
|
||||||
if (ext.CompareNoCase(kExt)==0 ||
|
|
||||||
ext.CompareNoCase(L"EXE") == 0)
|
|
||||||
{
|
|
||||||
_afterPart = kAfterPart;
|
|
||||||
basePart = name.Left(dotPos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int numLetters = 1;
|
|
||||||
bool splitStyle = false;
|
|
||||||
if (basePart.Right(numLetters) == L"1")
|
|
||||||
{
|
|
||||||
while (numLetters < basePart.Length())
|
|
||||||
{
|
|
||||||
if (basePart[basePart.Length() - numLetters - 1] != '0')
|
|
||||||
break;
|
|
||||||
numLetters++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
_unchangedPart = basePart.Left(basePart.Length() - numLetters);
|
|
||||||
_changedPart = basePart.Right(numLetters);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
UString GetNextName()
|
|
||||||
{
|
|
||||||
UString newName;
|
|
||||||
// if (_newStyle || !_first)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int numLetters = _changedPart.Length();
|
|
||||||
for (i = numLetters - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
wchar_t c = _changedPart[i];
|
|
||||||
if (c == L'9')
|
|
||||||
{
|
|
||||||
c = L'0';
|
|
||||||
newName = c + newName;
|
|
||||||
if (i == 0)
|
|
||||||
newName = UString(L'1') + newName;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
newName = UString(c) + newName;
|
|
||||||
i--;
|
|
||||||
for (; i >= 0; i--)
|
|
||||||
newName = _changedPart[i] + newName;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
_changedPart = newName;
|
|
||||||
}
|
|
||||||
_first = false;
|
|
||||||
return _unchangedPart + _changedPart + _afterPart;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||||
const UInt64 *maxCheckStartPosition,
|
const UInt64 *maxCheckStartPosition,
|
||||||
IArchiveOpenCallback *openArchiveCallback)
|
IArchiveOpenCallback *openArchiveCallback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
@@ -527,11 +415,6 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
|
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
|
||||||
#ifdef _7Z_VOL
|
|
||||||
CVolumeName seqName;
|
|
||||||
|
|
||||||
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
||||||
@@ -541,127 +424,22 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
|||||||
IID_ICryptoGetTextPassword, &getTextPassword);
|
IID_ICryptoGetTextPassword, &getTextPassword);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef _7Z_VOL
|
|
||||||
if (openArchiveCallback)
|
|
||||||
{
|
|
||||||
openArchiveCallbackTemp.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
|
|
||||||
}
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
CMyComPtr<IInStream> inStream;
|
|
||||||
if (!_volumes.IsEmpty())
|
|
||||||
{
|
|
||||||
if (!openVolumeCallback)
|
|
||||||
break;
|
|
||||||
if(_volumes.Size() == 1)
|
|
||||||
{
|
|
||||||
UString baseName;
|
|
||||||
{
|
|
||||||
NCOM::CPropVariant prop;
|
|
||||||
RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
|
|
||||||
if (prop.vt != VT_BSTR)
|
|
||||||
break;
|
|
||||||
baseName = prop.bstrVal;
|
|
||||||
}
|
|
||||||
seqName.InitName(baseName);
|
|
||||||
}
|
|
||||||
|
|
||||||
UString fullName = seqName.GetNextName();
|
|
||||||
HRESULT result = openVolumeCallback->GetStream(fullName, &inStream);
|
|
||||||
if (result == S_FALSE)
|
|
||||||
break;
|
|
||||||
if (result != S_OK)
|
|
||||||
return result;
|
|
||||||
if (!stream)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
inStream = stream;
|
|
||||||
|
|
||||||
CInArchive archive;
|
|
||||||
RINOK(archive.Open(inStream, maxCheckStartPosition));
|
|
||||||
|
|
||||||
_volumes.Add(CVolume());
|
|
||||||
CVolume &volume = _volumes.Back();
|
|
||||||
CArchiveDatabaseEx &database = volume.Database;
|
|
||||||
volume.Stream = inStream;
|
|
||||||
volume.StartRef2Index = _refs.Size();
|
|
||||||
|
|
||||||
HRESULT result = archive.ReadDatabase(database
|
|
||||||
#ifndef _NO_CRYPTO
|
|
||||||
, getTextPassword
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
if (result != S_OK)
|
|
||||||
{
|
|
||||||
_volumes.Clear();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
database.Fill();
|
|
||||||
for(int i = 0; i < database.Files.Size(); i++)
|
|
||||||
{
|
|
||||||
CRef refNew;
|
|
||||||
refNew.VolumeIndex = _volumes.Size() - 1;
|
|
||||||
refNew.ItemIndex = i;
|
|
||||||
_refs.Add(refNew);
|
|
||||||
/*
|
|
||||||
const CFileItem &file = database.Files[i];
|
|
||||||
int j;
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
for (j = _refs.Size() - 1; j >= 0; j--)
|
|
||||||
{
|
|
||||||
CRef2 &ref2 = _refs[j];
|
|
||||||
const CRef &ref = ref2.Refs.Back();
|
|
||||||
const CVolume &volume2 = _volumes[ref.VolumeIndex];
|
|
||||||
const CArchiveDatabaseEx &database2 = volume2.Database;
|
|
||||||
const CFileItem &file2 = database2.Files[ref.ItemIndex];
|
|
||||||
if (file2.Name.CompareNoCase(file.Name) == 0)
|
|
||||||
{
|
|
||||||
if (!file.IsStartPosDefined)
|
|
||||||
continue;
|
|
||||||
if (file.StartPos != ref2.StartPos + ref2.UnPackSize)
|
|
||||||
continue;
|
|
||||||
ref2.Refs.Add(refNew);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
j = -1;
|
|
||||||
if (j < 0)
|
|
||||||
{
|
|
||||||
CRef2 ref2New;
|
|
||||||
ref2New.Refs.Add(refNew);
|
|
||||||
j = _refs.Add(ref2New);
|
|
||||||
}
|
|
||||||
CRef2 &ref2 = _refs[j];
|
|
||||||
ref2.UnPackSize += file.UnPackSize;
|
|
||||||
ref2.PackSize += database.GetFilePackSize(i);
|
|
||||||
if (ref2.Refs.Size() == 1 && file.IsStartPosDefined)
|
|
||||||
ref2.StartPos = file.StartPos;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
if (database.Files.Size() != 1)
|
|
||||||
break;
|
|
||||||
const CFileItem &file = database.Files.Front();
|
|
||||||
if (!file.IsStartPosDefined)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
CInArchive archive;
|
CInArchive archive;
|
||||||
RINOK(archive.Open(stream, maxCheckStartPosition));
|
RINOK(archive.Open(stream, maxCheckStartPosition));
|
||||||
|
#ifndef _NO_CRYPTO
|
||||||
|
_passwordIsDefined = false;
|
||||||
|
UString password;
|
||||||
|
#endif
|
||||||
HRESULT result = archive.ReadDatabase(
|
HRESULT result = archive.ReadDatabase(
|
||||||
EXTERNAL_CODECS_VARS
|
EXTERNAL_CODECS_VARS
|
||||||
_database
|
_db
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, getTextPassword
|
, getTextPassword, _passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
_database.Fill();
|
_db.Fill();
|
||||||
_inStream = stream;
|
_inStream = stream;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
@@ -679,75 +457,12 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
|||||||
STDMETHODIMP CHandler::Close()
|
STDMETHODIMP CHandler::Close()
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
#ifdef _7Z_VOL
|
|
||||||
_volumes.Clear();
|
|
||||||
_refs.Clear();
|
|
||||||
#else
|
|
||||||
_inStream.Release();
|
_inStream.Release();
|
||||||
_database.Clear();
|
_db.Clear();
|
||||||
#endif
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
|
||||||
{
|
|
||||||
if (index != 0)
|
|
||||||
return E_INVALIDARG;
|
|
||||||
*stream = 0;
|
|
||||||
CMultiStream *streamSpec = new CMultiStream;
|
|
||||||
CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
|
|
||||||
|
|
||||||
UInt64 pos = 0;
|
|
||||||
const UString *fileName;
|
|
||||||
for (int i = 0; i < _refs.Size(); i++)
|
|
||||||
{
|
|
||||||
const CRef &ref = _refs[i];
|
|
||||||
const CVolume &volume = _volumes[ref.VolumeIndex];
|
|
||||||
const CArchiveDatabaseEx &database = volume.Database;
|
|
||||||
const CFileItem &file = database.Files[ref.ItemIndex];
|
|
||||||
if (i == 0)
|
|
||||||
fileName = &file.Name;
|
|
||||||
else
|
|
||||||
if (fileName->Compare(file.Name) != 0)
|
|
||||||
return S_FALSE;
|
|
||||||
if (!file.IsStartPosDefined)
|
|
||||||
return S_FALSE;
|
|
||||||
if (file.StartPos != pos)
|
|
||||||
return S_FALSE;
|
|
||||||
CNum folderIndex = database.FileIndexToFolderIndexMap[ref.ItemIndex];
|
|
||||||
if (folderIndex == kNumNoIndex)
|
|
||||||
{
|
|
||||||
if (file.UnPackSize != 0)
|
|
||||||
return E_FAIL;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (database.NumUnPackStreamsVector[folderIndex] != 1)
|
|
||||||
return S_FALSE;
|
|
||||||
const CFolder &folder = database.Folders[folderIndex];
|
|
||||||
if (folder.Coders.Size() != 1)
|
|
||||||
return S_FALSE;
|
|
||||||
const CCoderInfo &coder = folder.Coders.Front();
|
|
||||||
if (coder.NumInStreams != 1 || coder.NumOutStreams != 1)
|
|
||||||
return S_FALSE;
|
|
||||||
if (coder.MethodID != k_Copy)
|
|
||||||
return S_FALSE;
|
|
||||||
|
|
||||||
pos += file.UnPackSize;
|
|
||||||
CMultiStream::CSubStreamInfo subStreamInfo;
|
|
||||||
subStreamInfo.Stream = volume.Stream;
|
|
||||||
subStreamInfo.Pos = database.GetFolderStreamPos(folderIndex, 0);
|
|
||||||
subStreamInfo.Size = file.UnPackSize;
|
|
||||||
streamSpec->Streams.Add(subStreamInfo);
|
|
||||||
}
|
|
||||||
streamSpec->Init();
|
|
||||||
*stream = streamTemp.Detach();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __7Z_SET_PROPERTIES
|
#ifdef __7Z_SET_PROPERTIES
|
||||||
#ifdef EXTRACT_ONLY
|
#ifdef EXTRACT_ONLY
|
||||||
|
|
||||||
@@ -783,7 +498,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
|||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,56 +18,35 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
struct CRef
|
|
||||||
{
|
|
||||||
int VolumeIndex;
|
|
||||||
int ItemIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CVolume
|
|
||||||
{
|
|
||||||
int StartRef2Index;
|
|
||||||
CMyComPtr<IInStream> Stream;
|
|
||||||
CArchiveDatabaseEx Database;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __7Z_SET_PROPERTIES
|
#ifndef __7Z_SET_PROPERTIES
|
||||||
|
|
||||||
#ifdef EXTRACT_ONLY
|
#ifdef EXTRACT_ONLY
|
||||||
#ifdef COMPRESS_MT
|
#ifdef COMPRESS_MT
|
||||||
#define __7Z_SET_PROPERTIES
|
#define __7Z_SET_PROPERTIES
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define __7Z_SET_PROPERTIES
|
#define __7Z_SET_PROPERTIES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class CHandler:
|
class CHandler:
|
||||||
#ifndef EXTRACT_ONLY
|
#ifndef EXTRACT_ONLY
|
||||||
public NArchive::COutHandler,
|
public NArchive::COutHandler,
|
||||||
#endif
|
#endif
|
||||||
public IInArchive,
|
public IInArchive,
|
||||||
#ifdef _7Z_VOL
|
|
||||||
public IInArchiveGetStream,
|
|
||||||
#endif
|
|
||||||
#ifdef __7Z_SET_PROPERTIES
|
#ifdef __7Z_SET_PROPERTIES
|
||||||
public ISetProperties,
|
public ISetProperties,
|
||||||
#endif
|
#endif
|
||||||
#ifndef EXTRACT_ONLY
|
#ifndef EXTRACT_ONLY
|
||||||
public IOutArchive,
|
public IOutArchive,
|
||||||
#endif
|
#endif
|
||||||
PUBLIC_ISetCompressCodecsInfo
|
PUBLIC_ISetCompressCodecsInfo
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MY_QUERYINTERFACE_BEGIN2(IInArchive)
|
MY_QUERYINTERFACE_BEGIN2(IInArchive)
|
||||||
#ifdef _7Z_VOL
|
|
||||||
MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
|
|
||||||
#endif
|
|
||||||
#ifdef __7Z_SET_PROPERTIES
|
#ifdef __7Z_SET_PROPERTIES
|
||||||
MY_QUERYINTERFACE_ENTRY(ISetProperties)
|
MY_QUERYINTERFACE_ENTRY(ISetProperties)
|
||||||
#endif
|
#endif
|
||||||
@@ -80,10 +59,6 @@ public:
|
|||||||
|
|
||||||
INTERFACE_IInArchive(;)
|
INTERFACE_IInArchive(;)
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __7Z_SET_PROPERTIES
|
#ifdef __7Z_SET_PROPERTIES
|
||||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
|
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
|
||||||
#endif
|
#endif
|
||||||
@@ -97,12 +72,10 @@ public:
|
|||||||
CHandler();
|
CHandler();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef _7Z_VOL
|
|
||||||
CObjectVector<CVolume> _volumes;
|
|
||||||
CObjectVector<CRef> _refs;
|
|
||||||
#else
|
|
||||||
CMyComPtr<IInStream> _inStream;
|
CMyComPtr<IInStream> _inStream;
|
||||||
NArchive::N7z::CArchiveDatabaseEx _database;
|
NArchive::N7z::CArchiveDatabaseEx _db;
|
||||||
|
#ifndef _NO_CRYPTO
|
||||||
|
bool _passwordIsDefined;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTRACT_ONLY
|
#ifdef EXTRACT_ONLY
|
||||||
@@ -139,6 +112,8 @@ private:
|
|||||||
void FillPopIDs();
|
void FillPopIDs();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
DECL_EXTERNAL_CODECS_VARS
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ HRESULT CHandler::SetCompressionMethod(
|
|||||||
for (int j = 0; j < methodFull.Properties.Size(); j++)
|
for (int j = 0; j < methodFull.Properties.Size(); j++)
|
||||||
{
|
{
|
||||||
const CProp &prop = methodFull.Properties[j];
|
const CProp &prop = methodFull.Properties[j];
|
||||||
if ((prop.Id == NCoderPropID::kDictionarySize ||
|
if ((prop.Id == NCoderPropID::kDictionarySize ||
|
||||||
prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4)
|
prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4)
|
||||||
{
|
{
|
||||||
_numSolidBytes = ((UInt64)prop.Value.ulVal) << 7;
|
_numSolidBytes = ((UInt64)prop.Value.ulVal) << 7;
|
||||||
@@ -185,17 +185,20 @@ HRESULT CHandler::SetCompressionMethod(
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, CArchiveFileTime &filetime, bool &filetimeIsDefined)
|
static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, bool writeTime, PROPID propID, UInt64 &ft, bool &ftDefined)
|
||||||
{
|
{
|
||||||
filetimeIsDefined = false;
|
ft = 0;
|
||||||
NCOM::CPropVariant propVariant;
|
ftDefined = false;
|
||||||
RINOK(updateCallback->GetProperty(index, propID, &propVariant));
|
if (!writeTime)
|
||||||
if (propVariant.vt == VT_FILETIME)
|
return S_OK;
|
||||||
|
NCOM::CPropVariant prop;
|
||||||
|
RINOK(updateCallback->GetProperty(index, propID, &prop));
|
||||||
|
if (prop.vt == VT_FILETIME)
|
||||||
{
|
{
|
||||||
filetime = propVariant.filetime;
|
ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32);
|
||||||
filetimeIsDefined = true;
|
ftDefined = true;
|
||||||
}
|
}
|
||||||
else if (propVariant.vt != VT_EMPTY)
|
else if (prop.vt != VT_EMPTY)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -205,7 +208,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
|
|
||||||
const CArchiveDatabaseEx *database = 0;
|
const CArchiveDatabaseEx *db = 0;
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
if(_volumes.Size() > 1)
|
if(_volumes.Size() > 1)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
@@ -213,139 +216,131 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
if (_volumes.Size() == 1)
|
if (_volumes.Size() == 1)
|
||||||
{
|
{
|
||||||
volume = &_volumes.Front();
|
volume = &_volumes.Front();
|
||||||
database = &volume->Database;
|
db = &volume->Database;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (_inStream != 0)
|
if (_inStream != 0)
|
||||||
database = &_database;
|
db = &_db;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// CRecordVector<bool> compressStatuses;
|
|
||||||
CObjectVector<CUpdateItem> updateItems;
|
CObjectVector<CUpdateItem> updateItems;
|
||||||
// CRecordVector<UInt32> copyIndices;
|
|
||||||
|
|
||||||
// CMyComPtr<IUpdateCallback2> updateCallback2;
|
for (UInt32 i = 0; i < numItems; i++)
|
||||||
// updateCallback->QueryInterface(&updateCallback2);
|
|
||||||
|
|
||||||
for(UInt32 i = 0; i < numItems; i++)
|
|
||||||
{
|
{
|
||||||
Int32 newData;
|
Int32 newData;
|
||||||
Int32 newProperties;
|
Int32 newProperties;
|
||||||
UInt32 indexInArchive;
|
UInt32 indexInArchive;
|
||||||
if (!updateCallback)
|
if (!updateCallback)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
RINOK(updateCallback->GetUpdateItemInfo(i,
|
RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProperties, &indexInArchive));
|
||||||
&newData, &newProperties, &indexInArchive));
|
CUpdateItem ui;
|
||||||
CUpdateItem updateItem;
|
ui.NewProperties = IntToBool(newProperties);
|
||||||
updateItem.NewProperties = IntToBool(newProperties);
|
ui.NewData = IntToBool(newData);
|
||||||
updateItem.NewData = IntToBool(newData);
|
ui.IndexInArchive = indexInArchive;
|
||||||
updateItem.IndexInArchive = indexInArchive;
|
ui.IndexInClient = i;
|
||||||
updateItem.IndexInClient = i;
|
ui.IsAnti = false;
|
||||||
updateItem.IsAnti = false;
|
ui.Size = 0;
|
||||||
updateItem.Size = 0;
|
|
||||||
|
|
||||||
if (updateItem.IndexInArchive != -1)
|
if (ui.IndexInArchive != -1)
|
||||||
{
|
{
|
||||||
const CFileItem &fileItem = database->Files[updateItem.IndexInArchive];
|
const CFileItem &fi = db->Files[ui.IndexInArchive];
|
||||||
updateItem.Name = fileItem.Name;
|
ui.Name = fi.Name;
|
||||||
updateItem.IsDirectory = fileItem.IsDirectory;
|
ui.IsDir = fi.IsDir;
|
||||||
updateItem.Size = fileItem.UnPackSize;
|
ui.Size = fi.Size;
|
||||||
updateItem.IsAnti = fileItem.IsAnti;
|
ui.IsAnti = db->IsItemAnti(ui.IndexInArchive);
|
||||||
|
|
||||||
updateItem.CreationTime = fileItem.CreationTime;
|
ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime);
|
||||||
updateItem.IsCreationTimeDefined = fileItem.IsCreationTimeDefined;
|
ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime);
|
||||||
updateItem.LastWriteTime = fileItem.LastWriteTime;
|
ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime);
|
||||||
updateItem.IsLastWriteTimeDefined = fileItem.IsLastWriteTimeDefined;
|
|
||||||
updateItem.LastAccessTime = fileItem.LastAccessTime;
|
|
||||||
updateItem.IsLastAccessTimeDefined = fileItem.IsLastAccessTimeDefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateItem.NewProperties)
|
if (ui.NewProperties)
|
||||||
{
|
{
|
||||||
bool nameIsDefined;
|
bool nameIsDefined;
|
||||||
bool folderStatusIsDefined;
|
bool folderStatusIsDefined;
|
||||||
{
|
{
|
||||||
NCOM::CPropVariant propVariant;
|
NCOM::CPropVariant prop;
|
||||||
RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant));
|
RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop));
|
||||||
if (propVariant.vt == VT_EMPTY)
|
if (prop.vt == VT_EMPTY)
|
||||||
updateItem.AttributesAreDefined = false;
|
ui.AttribDefined = false;
|
||||||
else if (propVariant.vt != VT_UI4)
|
else if (prop.vt != VT_UI4)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
updateItem.Attributes = propVariant.ulVal;
|
ui.Attrib = prop.ulVal;
|
||||||
updateItem.AttributesAreDefined = true;
|
ui.AttribDefined = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RINOK(GetTime(updateCallback, i, kpidCreationTime, updateItem.CreationTime, updateItem.IsCreationTimeDefined));
|
// we need MTime to sort files.
|
||||||
RINOK(GetTime(updateCallback, i, kpidLastWriteTime, updateItem.LastWriteTime , updateItem.IsLastWriteTimeDefined));
|
RINOK(GetTime(updateCallback, i, WriteCTime, kpidCTime, ui.CTime, ui.CTimeDefined));
|
||||||
RINOK(GetTime(updateCallback, i, kpidLastAccessTime, updateItem.LastAccessTime, updateItem.IsLastAccessTimeDefined));
|
RINOK(GetTime(updateCallback, i, WriteATime, kpidATime, ui.ATime, ui.ATimeDefined));
|
||||||
|
RINOK(GetTime(updateCallback, i, true, kpidMTime, ui.MTime, ui.MTimeDefined));
|
||||||
|
|
||||||
{
|
{
|
||||||
NCOM::CPropVariant propVariant;
|
NCOM::CPropVariant prop;
|
||||||
RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant));
|
RINOK(updateCallback->GetProperty(i, kpidPath, &prop));
|
||||||
if (propVariant.vt == VT_EMPTY)
|
if (prop.vt == VT_EMPTY)
|
||||||
nameIsDefined = false;
|
nameIsDefined = false;
|
||||||
else if (propVariant.vt != VT_BSTR)
|
else if (prop.vt != VT_BSTR)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
updateItem.Name = NItemName::MakeLegalName(propVariant.bstrVal);
|
ui.Name = NItemName::MakeLegalName(prop.bstrVal);
|
||||||
nameIsDefined = true;
|
nameIsDefined = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
NCOM::CPropVariant propVariant;
|
NCOM::CPropVariant prop;
|
||||||
RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant));
|
RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop));
|
||||||
if (propVariant.vt == VT_EMPTY)
|
if (prop.vt == VT_EMPTY)
|
||||||
folderStatusIsDefined = false;
|
folderStatusIsDefined = false;
|
||||||
else if (propVariant.vt != VT_BOOL)
|
else if (prop.vt != VT_BOOL)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE);
|
ui.IsDir = (prop.boolVal != VARIANT_FALSE);
|
||||||
folderStatusIsDefined = true;
|
folderStatusIsDefined = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
NCOM::CPropVariant propVariant;
|
NCOM::CPropVariant prop;
|
||||||
RINOK(updateCallback->GetProperty(i, kpidIsAnti, &propVariant));
|
RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop));
|
||||||
if (propVariant.vt == VT_EMPTY)
|
if (prop.vt == VT_EMPTY)
|
||||||
updateItem.IsAnti = false;
|
ui.IsAnti = false;
|
||||||
else if (propVariant.vt != VT_BOOL)
|
else if (prop.vt != VT_BOOL)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
else
|
else
|
||||||
updateItem.IsAnti = (propVariant.boolVal != VARIANT_FALSE);
|
ui.IsAnti = (prop.boolVal != VARIANT_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateItem.IsAnti)
|
if (ui.IsAnti)
|
||||||
{
|
{
|
||||||
updateItem.AttributesAreDefined = false;
|
ui.AttribDefined = false;
|
||||||
|
|
||||||
updateItem.IsCreationTimeDefined = false;
|
ui.CTimeDefined = false;
|
||||||
updateItem.IsLastWriteTimeDefined = false;
|
ui.ATimeDefined = false;
|
||||||
updateItem.IsLastAccessTimeDefined = false;
|
ui.MTimeDefined = false;
|
||||||
|
|
||||||
updateItem.Size = 0;
|
ui.Size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!folderStatusIsDefined && updateItem.AttributesAreDefined)
|
if (!folderStatusIsDefined && ui.AttribDefined)
|
||||||
updateItem.SetDirectoryStatusFromAttributes();
|
ui.SetDirStatusFromAttrib();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateItem.NewData)
|
if (ui.NewData)
|
||||||
{
|
{
|
||||||
NCOM::CPropVariant propVariant;
|
NCOM::CPropVariant prop;
|
||||||
RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
|
RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
|
||||||
if (propVariant.vt != VT_UI8)
|
if (prop.vt != VT_UI8)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
updateItem.Size = (UInt64)propVariant.uhVal.QuadPart;
|
ui.Size = (UInt64)prop.uhVal.QuadPart;
|
||||||
if (updateItem.Size != 0 && updateItem.IsAnti)
|
if (ui.Size != 0 && ui.IsAnti)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
updateItems.Add(updateItem);
|
updateItems.Add(ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
CCompressionMethodMode methodMode, headerMethod;
|
CCompressionMethodMode methodMode, headerMethod;
|
||||||
@@ -359,10 +354,18 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
|
|
||||||
bool compressMainHeader = _compressHeaders; // check it
|
bool compressMainHeader = _compressHeaders; // check it
|
||||||
|
|
||||||
|
bool encryptHeaders = false;
|
||||||
|
|
||||||
if (methodMode.PasswordIsDefined)
|
if (methodMode.PasswordIsDefined)
|
||||||
{
|
{
|
||||||
compressMainHeader = true;
|
if (_encryptHeadersSpecified)
|
||||||
if(_encryptHeaders)
|
encryptHeaders = _encryptHeaders;
|
||||||
|
#ifndef _NO_CRYPTO
|
||||||
|
else
|
||||||
|
encryptHeaders = _passwordIsDefined;
|
||||||
|
#endif
|
||||||
|
compressMainHeader = true;
|
||||||
|
if(encryptHeaders)
|
||||||
RINOK(SetPassword(headerMethod, updateCallback));
|
RINOK(SetPassword(headerMethod, updateCallback));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,32 +374,42 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
|
|
||||||
CUpdateOptions options;
|
CUpdateOptions options;
|
||||||
options.Method = &methodMode;
|
options.Method = &methodMode;
|
||||||
options.HeaderMethod = (_compressHeaders ||
|
options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0;
|
||||||
(methodMode.PasswordIsDefined && _encryptHeaders)) ?
|
|
||||||
&headerMethod : 0;
|
|
||||||
options.UseFilters = _level != 0 && _autoFilter;
|
options.UseFilters = _level != 0 && _autoFilter;
|
||||||
options.MaxFilter = _level >= 8;
|
options.MaxFilter = _level >= 8;
|
||||||
|
|
||||||
options.HeaderOptions.CompressMainHeader = compressMainHeader;
|
options.HeaderOptions.CompressMainHeader = compressMainHeader;
|
||||||
options.HeaderOptions.WriteModified = WriteModified;
|
options.HeaderOptions.WriteCTime = WriteCTime;
|
||||||
options.HeaderOptions.WriteCreated = WriteCreated;
|
options.HeaderOptions.WriteATime = WriteATime;
|
||||||
options.HeaderOptions.WriteAccessed = WriteAccessed;
|
options.HeaderOptions.WriteMTime = WriteMTime;
|
||||||
|
|
||||||
options.NumSolidFiles = _numSolidFiles;
|
options.NumSolidFiles = _numSolidFiles;
|
||||||
options.NumSolidBytes = _numSolidBytes;
|
options.NumSolidBytes = _numSolidBytes;
|
||||||
options.SolidExtension = _solidExtension;
|
options.SolidExtension = _solidExtension;
|
||||||
options.RemoveSfxBlock = _removeSfxBlock;
|
options.RemoveSfxBlock = _removeSfxBlock;
|
||||||
options.VolumeMode = _volumeMode;
|
options.VolumeMode = _volumeMode;
|
||||||
return Update(
|
|
||||||
|
COutArchive archive;
|
||||||
|
CArchiveDatabase newDatabase;
|
||||||
|
HRESULT res = Update(
|
||||||
EXTERNAL_CODECS_VARS
|
EXTERNAL_CODECS_VARS
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
volume ? volume->Stream: 0,
|
volume ? volume->Stream: 0,
|
||||||
volume ? database: 0,
|
volume ? db : 0,
|
||||||
#else
|
#else
|
||||||
_inStream,
|
_inStream,
|
||||||
database,
|
db,
|
||||||
#endif
|
#endif
|
||||||
updateItems, outStream, updateCallback, options);
|
updateItems,
|
||||||
|
archive, newDatabase, outStream, updateCallback, options);
|
||||||
|
|
||||||
|
RINOK(res);
|
||||||
|
|
||||||
|
updateItems.ClearAndFree();
|
||||||
|
|
||||||
|
return archive.WriteDatabase(EXTERNAL_CODECS_VARS
|
||||||
|
newDatabase, options.HeaderMethod, options.HeaderOptions);
|
||||||
|
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,6 +472,6 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
|||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ Byte kFinishSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C +
|
|||||||
class SignatureInitializer
|
class SignatureInitializer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SignatureInitializer()
|
SignatureInitializer()
|
||||||
{
|
{
|
||||||
kSignature[0]--;
|
kSignature[0]--;
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
kFinishSignature[0]--;
|
kFinishSignature[0]--;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ extern Byte kSignature[kSignatureSize];
|
|||||||
|
|
||||||
// #define _7Z_VOL
|
// #define _7Z_VOL
|
||||||
// 7z-MultiVolume is not finished yet.
|
// 7z-MultiVolume is not finished yet.
|
||||||
// It can work already, but I still do not like some
|
// It can work already, but I still do not like some
|
||||||
// things of that new multivolume format.
|
// things of that new multivolume format.
|
||||||
// So please keep it commented.
|
// So please keep it commented.
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ namespace NID
|
|||||||
kFilesInfo,
|
kFilesInfo,
|
||||||
|
|
||||||
kPackInfo,
|
kPackInfo,
|
||||||
kUnPackInfo,
|
kUnpackInfo,
|
||||||
kSubStreamsInfo,
|
kSubStreamsInfo,
|
||||||
|
|
||||||
kSize,
|
kSize,
|
||||||
@@ -71,23 +71,24 @@ namespace NID
|
|||||||
|
|
||||||
kFolder,
|
kFolder,
|
||||||
|
|
||||||
kCodersUnPackSize,
|
kCodersUnpackSize,
|
||||||
kNumUnPackStream,
|
kNumUnpackStream,
|
||||||
|
|
||||||
kEmptyStream,
|
kEmptyStream,
|
||||||
kEmptyFile,
|
kEmptyFile,
|
||||||
kAnti,
|
kAnti,
|
||||||
|
|
||||||
kName,
|
kName,
|
||||||
kCreationTime,
|
kCTime,
|
||||||
kLastAccessTime,
|
kATime,
|
||||||
kLastWriteTime,
|
kMTime,
|
||||||
kWinAttributes,
|
kWinAttributes,
|
||||||
kComment,
|
kComment,
|
||||||
|
|
||||||
kEncodedHeader,
|
kEncodedHeader,
|
||||||
|
|
||||||
kStartPos
|
kStartPos,
|
||||||
|
kDummy
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+239
-254
@@ -6,13 +6,17 @@
|
|||||||
#include "7zDecode.h"
|
#include "7zDecode.h"
|
||||||
#include "../../Common/StreamObjects.h"
|
#include "../../Common/StreamObjects.h"
|
||||||
#include "../../Common/StreamUtils.h"
|
#include "../../Common/StreamUtils.h"
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "../../../../C/7zCrc.h"
|
#include "../../../../C/7zCrc.h"
|
||||||
#include "../../../../C/CpuArch.h"
|
#include "../../../../C/CpuArch.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader
|
#define Get16(p) GetUi16(p)
|
||||||
|
#define Get32(p) GetUi32(p)
|
||||||
|
#define Get64(p) GetUi64(p)
|
||||||
|
|
||||||
|
// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader
|
||||||
#ifndef _SFX
|
#ifndef _SFX
|
||||||
#define FORMAT_7Z_RECOVERY
|
#define FORMAT_7Z_RECOVERY
|
||||||
#endif
|
#endif
|
||||||
@@ -36,7 +40,7 @@ public:
|
|||||||
{
|
{
|
||||||
kUnsupportedVersion = 0,
|
kUnsupportedVersion = 0,
|
||||||
kUnsupported,
|
kUnsupported,
|
||||||
kIncorrect,
|
kIncorrect,
|
||||||
kEndOfData,
|
kEndOfData,
|
||||||
} Cause;
|
} Cause;
|
||||||
CInArchiveException(CCauseType cause): Cause(cause) {};
|
CInArchiveException(CCauseType cause): Cause(cause) {};
|
||||||
@@ -97,16 +101,6 @@ void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *d
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LITTLE_ENDIAN_UNALIGN
|
|
||||||
static inline UInt16 GetUInt16FromMem(const Byte *p) { return *(const UInt16 *)p; }
|
|
||||||
static inline UInt32 GetUInt32FromMem(const Byte *p) { return *(const UInt32 *)p; }
|
|
||||||
static inline UInt64 GetUInt64FromMem(const Byte *p) { return *(const UInt64 *)p; }
|
|
||||||
#else
|
|
||||||
static inline UInt16 GetUInt16FromMem(const Byte *p) { return p[0] | ((UInt16)p[1] << 8); }
|
|
||||||
static inline UInt32 GetUInt32FromMem(const Byte *p) { return p[0] | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16) | ((UInt32)p[3] << 24); }
|
|
||||||
static inline UInt64 GetUInt64FromMem(const Byte *p) { return GetUInt32FromMem(p) | ((UInt64)GetUInt32FromMem(p + 4) << 32); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Byte CInByte2::ReadByte()
|
Byte CInByte2::ReadByte()
|
||||||
{
|
{
|
||||||
if (_pos >= _size)
|
if (_pos >= _size)
|
||||||
@@ -126,6 +120,7 @@ void CInByte2::SkeepData(UInt64 size)
|
|||||||
{
|
{
|
||||||
if (size > _size - _pos)
|
if (size > _size - _pos)
|
||||||
ThrowEndOfData();
|
ThrowEndOfData();
|
||||||
|
_pos += (size_t)size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInByte2::SkeepData()
|
void CInByte2::SkeepData()
|
||||||
@@ -157,8 +152,8 @@ UInt64 CInByte2::ReadNumber()
|
|||||||
}
|
}
|
||||||
|
|
||||||
CNum CInByte2::ReadNum()
|
CNum CInByte2::ReadNum()
|
||||||
{
|
{
|
||||||
UInt64 value = ReadNumber();
|
UInt64 value = ReadNumber();
|
||||||
if (value > kNumMax)
|
if (value > kNumMax)
|
||||||
ThrowUnsupported();
|
ThrowUnsupported();
|
||||||
return (CNum)value;
|
return (CNum)value;
|
||||||
@@ -168,7 +163,7 @@ UInt32 CInByte2::ReadUInt32()
|
|||||||
{
|
{
|
||||||
if (_pos + 4 > _size)
|
if (_pos + 4 > _size)
|
||||||
ThrowEndOfData();
|
ThrowEndOfData();
|
||||||
UInt32 res = GetUInt32FromMem(_buffer + _pos);
|
UInt32 res = Get32(_buffer + _pos);
|
||||||
_pos += 4;
|
_pos += 4;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -177,7 +172,7 @@ UInt64 CInByte2::ReadUInt64()
|
|||||||
{
|
{
|
||||||
if (_pos + 8 > _size)
|
if (_pos + 8 > _size)
|
||||||
ThrowEndOfData();
|
ThrowEndOfData();
|
||||||
UInt64 res = GetUInt64FromMem(_buffer + _pos);
|
UInt64 res = Get64(_buffer + _pos);
|
||||||
_pos += 8;
|
_pos += 8;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -200,9 +195,8 @@ void CInByte2::ReadString(UString &s)
|
|||||||
ThrowUnsupported();
|
ThrowUnsupported();
|
||||||
wchar_t *p = s.GetBuffer(len);
|
wchar_t *p = s.GetBuffer(len);
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < len; i++, buf += 2)
|
for (i = 0; i < len; i++, buf += 2)
|
||||||
p[i] = (wchar_t)GetUInt16FromMem(buf);
|
p[i] = (wchar_t)Get16(buf);
|
||||||
p[i] = 0;
|
|
||||||
s.ReleaseBuffer(len);
|
s.ReleaseBuffer(len);
|
||||||
_pos += rem + 2;
|
_pos += rem + 2;
|
||||||
}
|
}
|
||||||
@@ -234,23 +228,32 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
|
|||||||
if (searchHeaderSizeLimit != NULL)
|
if (searchHeaderSizeLimit != NULL)
|
||||||
if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
|
if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
|
||||||
break;
|
break;
|
||||||
UInt32 numReadBytes = kBufferSize - numPrevBytes;
|
do
|
||||||
UInt32 processedSize;
|
{
|
||||||
RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
|
UInt32 numReadBytes = kBufferSize - numPrevBytes;
|
||||||
UInt32 numBytesInBuffer = numPrevBytes + processedSize;
|
UInt32 processedSize;
|
||||||
if (numBytesInBuffer < kHeaderSize)
|
RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
|
||||||
break;
|
numPrevBytes += processedSize;
|
||||||
UInt32 numTests = numBytesInBuffer - kHeaderSize + 1;
|
if (processedSize == 0)
|
||||||
for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
|
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;
|
||||||
if (TestSignatureCandidate(buffer + pos))
|
if (TestSignatureCandidate(buffer + pos))
|
||||||
{
|
{
|
||||||
memcpy(_header, buffer + pos, kHeaderSize);
|
memcpy(_header, buffer + pos, kHeaderSize);
|
||||||
|
curTestPos += pos;
|
||||||
_arhiveBeginStreamPosition = curTestPos;
|
_arhiveBeginStreamPosition = curTestPos;
|
||||||
return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL);
|
return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
numPrevBytes = numBytesInBuffer - numTests;
|
curTestPos += numTests;
|
||||||
|
numPrevBytes -= numTests;
|
||||||
memmove(buffer, buffer + numTests, numPrevBytes);
|
memmove(buffer, buffer + numTests, numPrevBytes);
|
||||||
}
|
}
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
@@ -259,6 +262,7 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
|
|||||||
// S_FALSE means that file is not archive
|
// S_FALSE means that file is not archive
|
||||||
HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
|
HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
|
||||||
{
|
{
|
||||||
|
HeadersSize = 0;
|
||||||
Close();
|
Close();
|
||||||
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
|
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
|
||||||
RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
|
RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
|
||||||
@@ -338,7 +342,7 @@ void CInArchive::GetNextFolderItem(CFolder &folder)
|
|||||||
{
|
{
|
||||||
CBindPair bindPair;
|
CBindPair bindPair;
|
||||||
bindPair.InIndex = ReadNum();
|
bindPair.InIndex = ReadNum();
|
||||||
bindPair.OutIndex = ReadNum();
|
bindPair.OutIndex = ReadNum();
|
||||||
folder.BindPairs.Add(bindPair);
|
folder.BindPairs.Add(bindPair);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,7 +358,7 @@ void CInArchive::GetNextFolderItem(CFolder &folder)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
for(i = 0; i < numPackedStreams; i++)
|
for (i = 0; i < numPackedStreams; i++)
|
||||||
folder.PackStreams.Add(ReadNum());
|
folder.PackStreams.Add(ReadNum());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,13 +376,13 @@ void CInArchive::WaitAttribute(UInt64 attribute)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CInArchive::ReadHashDigests(int numItems,
|
void CInArchive::ReadHashDigests(int numItems,
|
||||||
CRecordVector<bool> &digestsDefined,
|
CRecordVector<bool> &digestsDefined,
|
||||||
CRecordVector<UInt32> &digests)
|
CRecordVector<UInt32> &digests)
|
||||||
{
|
{
|
||||||
ReadBoolVector2(numItems, digestsDefined);
|
ReadBoolVector2(numItems, digestsDefined);
|
||||||
digests.Clear();
|
digests.Clear();
|
||||||
digests.Reserve(numItems);
|
digests.Reserve(numItems);
|
||||||
for(int i = 0; i < numItems; i++)
|
for (int i = 0; i < numItems; i++)
|
||||||
{
|
{
|
||||||
UInt32 crc = 0;
|
UInt32 crc = 0;
|
||||||
if (digestsDefined[i])
|
if (digestsDefined[i])
|
||||||
@@ -410,7 +414,7 @@ void CInArchive::ReadPackInfo(
|
|||||||
break;
|
break;
|
||||||
if (type == NID::kCRC)
|
if (type == NID::kCRC)
|
||||||
{
|
{
|
||||||
ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs);
|
ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
SkeepData();
|
SkeepData();
|
||||||
@@ -421,7 +425,7 @@ void CInArchive::ReadPackInfo(
|
|||||||
packCRCsDefined.Clear();
|
packCRCsDefined.Clear();
|
||||||
packCRCs.Reserve(numPackStreams);
|
packCRCs.Reserve(numPackStreams);
|
||||||
packCRCs.Clear();
|
packCRCs.Clear();
|
||||||
for(CNum i = 0; i < numPackStreams; i++)
|
for (CNum i = 0; i < numPackStreams; i++)
|
||||||
{
|
{
|
||||||
packCRCsDefined.Add(false);
|
packCRCsDefined.Add(false);
|
||||||
packCRCs.Add(0);
|
packCRCs.Add(0);
|
||||||
@@ -429,7 +433,7 @@ void CInArchive::ReadPackInfo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInArchive::ReadUnPackInfo(
|
void CInArchive::ReadUnpackInfo(
|
||||||
const CObjectVector<CByteBuffer> *dataVector,
|
const CObjectVector<CByteBuffer> *dataVector,
|
||||||
CObjectVector<CFolder> &folders)
|
CObjectVector<CFolder> &folders)
|
||||||
{
|
{
|
||||||
@@ -441,23 +445,23 @@ void CInArchive::ReadUnPackInfo(
|
|||||||
streamSwitch.Set(this, dataVector);
|
streamSwitch.Set(this, dataVector);
|
||||||
folders.Clear();
|
folders.Clear();
|
||||||
folders.Reserve(numFolders);
|
folders.Reserve(numFolders);
|
||||||
for(CNum i = 0; i < numFolders; i++)
|
for (CNum i = 0; i < numFolders; i++)
|
||||||
{
|
{
|
||||||
folders.Add(CFolder());
|
folders.Add(CFolder());
|
||||||
GetNextFolderItem(folders.Back());
|
GetNextFolderItem(folders.Back());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WaitAttribute(NID::kCodersUnPackSize);
|
WaitAttribute(NID::kCodersUnpackSize);
|
||||||
|
|
||||||
CNum i;
|
CNum i;
|
||||||
for (i = 0; i < numFolders; i++)
|
for (i = 0; i < numFolders; i++)
|
||||||
{
|
{
|
||||||
CFolder &folder = folders[i];
|
CFolder &folder = folders[i];
|
||||||
CNum numOutStreams = folder.GetNumOutStreams();
|
CNum numOutStreams = folder.GetNumOutStreams();
|
||||||
folder.UnPackSizes.Reserve(numOutStreams);
|
folder.UnpackSizes.Reserve(numOutStreams);
|
||||||
for (CNum j = 0; j < numOutStreams; j++)
|
for (CNum j = 0; j < numOutStreams; j++)
|
||||||
folder.UnPackSizes.Add(ReadNumber());
|
folder.UnpackSizes.Add(ReadNumber());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
@@ -469,12 +473,12 @@ void CInArchive::ReadUnPackInfo(
|
|||||||
{
|
{
|
||||||
CRecordVector<bool> crcsDefined;
|
CRecordVector<bool> crcsDefined;
|
||||||
CRecordVector<UInt32> crcs;
|
CRecordVector<UInt32> crcs;
|
||||||
ReadHashDigests(numFolders, crcsDefined, crcs);
|
ReadHashDigests(numFolders, crcsDefined, crcs);
|
||||||
for(i = 0; i < numFolders; i++)
|
for (i = 0; i < numFolders; i++)
|
||||||
{
|
{
|
||||||
CFolder &folder = folders[i];
|
CFolder &folder = folders[i];
|
||||||
folder.UnPackCRCDefined = crcsDefined[i];
|
folder.UnpackCRCDefined = crcsDefined[i];
|
||||||
folder.UnPackCRC = crcs[i];
|
folder.UnpackCRC = crcs[i];
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -484,21 +488,21 @@ void CInArchive::ReadUnPackInfo(
|
|||||||
|
|
||||||
void CInArchive::ReadSubStreamsInfo(
|
void CInArchive::ReadSubStreamsInfo(
|
||||||
const CObjectVector<CFolder> &folders,
|
const CObjectVector<CFolder> &folders,
|
||||||
CRecordVector<CNum> &numUnPackStreamsInFolders,
|
CRecordVector<CNum> &numUnpackStreamsInFolders,
|
||||||
CRecordVector<UInt64> &unPackSizes,
|
CRecordVector<UInt64> &unpackSizes,
|
||||||
CRecordVector<bool> &digestsDefined,
|
CRecordVector<bool> &digestsDefined,
|
||||||
CRecordVector<UInt32> &digests)
|
CRecordVector<UInt32> &digests)
|
||||||
{
|
{
|
||||||
numUnPackStreamsInFolders.Clear();
|
numUnpackStreamsInFolders.Clear();
|
||||||
numUnPackStreamsInFolders.Reserve(folders.Size());
|
numUnpackStreamsInFolders.Reserve(folders.Size());
|
||||||
UInt64 type;
|
UInt64 type;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
type = ReadID();
|
type = ReadID();
|
||||||
if (type == NID::kNumUnPackStream)
|
if (type == NID::kNumUnpackStream)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < folders.Size(); i++)
|
for (int i = 0; i < folders.Size(); i++)
|
||||||
numUnPackStreamsInFolders.Add(ReadNum());
|
numUnpackStreamsInFolders.Add(ReadNum());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (type == NID::kCRC || type == NID::kSize)
|
if (type == NID::kCRC || type == NID::kSize)
|
||||||
@@ -508,16 +512,16 @@ void CInArchive::ReadSubStreamsInfo(
|
|||||||
SkeepData();
|
SkeepData();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numUnPackStreamsInFolders.IsEmpty())
|
if (numUnpackStreamsInFolders.IsEmpty())
|
||||||
for(int i = 0; i < folders.Size(); i++)
|
for (int i = 0; i < folders.Size(); i++)
|
||||||
numUnPackStreamsInFolders.Add(1);
|
numUnpackStreamsInFolders.Add(1);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
|
for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
|
||||||
{
|
{
|
||||||
// v3.13 incorrectly worked with empty folders
|
// v3.13 incorrectly worked with empty folders
|
||||||
// v4.07: we check that folder is empty
|
// v4.07: we check that folder is empty
|
||||||
CNum numSubstreams = numUnPackStreamsInFolders[i];
|
CNum numSubstreams = numUnpackStreamsInFolders[i];
|
||||||
if (numSubstreams == 0)
|
if (numSubstreams == 0)
|
||||||
continue;
|
continue;
|
||||||
UInt64 sum = 0;
|
UInt64 sum = 0;
|
||||||
@@ -525,20 +529,20 @@ void CInArchive::ReadSubStreamsInfo(
|
|||||||
if (type == NID::kSize)
|
if (type == NID::kSize)
|
||||||
{
|
{
|
||||||
UInt64 size = ReadNumber();
|
UInt64 size = ReadNumber();
|
||||||
unPackSizes.Add(size);
|
unpackSizes.Add(size);
|
||||||
sum += size;
|
sum += size;
|
||||||
}
|
}
|
||||||
unPackSizes.Add(folders[i].GetUnPackSize() - sum);
|
unpackSizes.Add(folders[i].GetUnpackSize() - sum);
|
||||||
}
|
}
|
||||||
if (type == NID::kSize)
|
if (type == NID::kSize)
|
||||||
type = ReadID();
|
type = ReadID();
|
||||||
|
|
||||||
int numDigests = 0;
|
int numDigests = 0;
|
||||||
int numDigestsTotal = 0;
|
int numDigestsTotal = 0;
|
||||||
for(i = 0; i < folders.Size(); i++)
|
for (i = 0; i < folders.Size(); i++)
|
||||||
{
|
{
|
||||||
CNum numSubstreams = numUnPackStreamsInFolders[i];
|
CNum numSubstreams = numUnpackStreamsInFolders[i];
|
||||||
if (numSubstreams != 1 || !folders[i].UnPackCRCDefined)
|
if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
|
||||||
numDigests += numSubstreams;
|
numDigests += numSubstreams;
|
||||||
numDigestsTotal += numSubstreams;
|
numDigestsTotal += numSubstreams;
|
||||||
}
|
}
|
||||||
@@ -547,18 +551,18 @@ void CInArchive::ReadSubStreamsInfo(
|
|||||||
{
|
{
|
||||||
if (type == NID::kCRC)
|
if (type == NID::kCRC)
|
||||||
{
|
{
|
||||||
CRecordVector<bool> digestsDefined2;
|
CRecordVector<bool> digestsDefined2;
|
||||||
CRecordVector<UInt32> digests2;
|
CRecordVector<UInt32> digests2;
|
||||||
ReadHashDigests(numDigests, digestsDefined2, digests2);
|
ReadHashDigests(numDigests, digestsDefined2, digests2);
|
||||||
int digestIndex = 0;
|
int digestIndex = 0;
|
||||||
for (i = 0; i < folders.Size(); i++)
|
for (i = 0; i < folders.Size(); i++)
|
||||||
{
|
{
|
||||||
CNum numSubstreams = numUnPackStreamsInFolders[i];
|
CNum numSubstreams = numUnpackStreamsInFolders[i];
|
||||||
const CFolder &folder = folders[i];
|
const CFolder &folder = folders[i];
|
||||||
if (numSubstreams == 1 && folder.UnPackCRCDefined)
|
if (numSubstreams == 1 && folder.UnpackCRCDefined)
|
||||||
{
|
{
|
||||||
digestsDefined.Add(true);
|
digestsDefined.Add(true);
|
||||||
digests.Add(folder.UnPackCRC);
|
digests.Add(folder.UnpackCRC);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
for (CNum j = 0; j < numSubstreams; j++, digestIndex++)
|
for (CNum j = 0; j < numSubstreams; j++, digestIndex++)
|
||||||
@@ -595,9 +599,9 @@ void CInArchive::ReadStreamsInfo(
|
|||||||
CRecordVector<bool> &packCRCsDefined,
|
CRecordVector<bool> &packCRCsDefined,
|
||||||
CRecordVector<UInt32> &packCRCs,
|
CRecordVector<UInt32> &packCRCs,
|
||||||
CObjectVector<CFolder> &folders,
|
CObjectVector<CFolder> &folders,
|
||||||
CRecordVector<CNum> &numUnPackStreamsInFolders,
|
CRecordVector<CNum> &numUnpackStreamsInFolders,
|
||||||
CRecordVector<UInt64> &unPackSizes,
|
CRecordVector<UInt64> &unpackSizes,
|
||||||
CRecordVector<bool> &digestsDefined,
|
CRecordVector<bool> &digestsDefined,
|
||||||
CRecordVector<UInt32> &digests)
|
CRecordVector<UInt32> &digests)
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
@@ -614,15 +618,15 @@ void CInArchive::ReadStreamsInfo(
|
|||||||
ReadPackInfo(dataOffset, packSizes, packCRCsDefined, packCRCs);
|
ReadPackInfo(dataOffset, packSizes, packCRCsDefined, packCRCs);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NID::kUnPackInfo:
|
case NID::kUnpackInfo:
|
||||||
{
|
{
|
||||||
ReadUnPackInfo(dataVector, folders);
|
ReadUnpackInfo(dataVector, folders);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NID::kSubStreamsInfo:
|
case NID::kSubStreamsInfo:
|
||||||
{
|
{
|
||||||
ReadSubStreamsInfo(folders, numUnPackStreamsInFolders,
|
ReadSubStreamsInfo(folders, numUnpackStreamsInFolders,
|
||||||
unPackSizes, digestsDefined, digests);
|
unpackSizes, digestsDefined, digests);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -637,7 +641,7 @@ void CInArchive::ReadBoolVector(int numItems, CBoolVector &v)
|
|||||||
v.Reserve(numItems);
|
v.Reserve(numItems);
|
||||||
Byte b = 0;
|
Byte b = 0;
|
||||||
Byte mask = 0;
|
Byte mask = 0;
|
||||||
for(int i = 0; i < numItems; i++)
|
for (int i = 0; i < numItems; i++)
|
||||||
{
|
{
|
||||||
if (mask == 0)
|
if (mask == 0)
|
||||||
{
|
{
|
||||||
@@ -663,54 +667,30 @@ void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v)
|
|||||||
v.Add(true);
|
v.Add(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector,
|
void CInArchive::ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
|
||||||
CObjectVector<CFileItem> &files, UInt32 type)
|
CUInt64DefVector &v, int numFiles)
|
||||||
{
|
{
|
||||||
CBoolVector boolVector;
|
ReadBoolVector2(numFiles, v.Defined);
|
||||||
ReadBoolVector2(files.Size(), boolVector);
|
|
||||||
|
|
||||||
CStreamSwitch streamSwitch;
|
CStreamSwitch streamSwitch;
|
||||||
streamSwitch.Set(this, &dataVector);
|
streamSwitch.Set(this, &dataVector);
|
||||||
|
v.Values.Reserve(numFiles);
|
||||||
|
|
||||||
for(int i = 0; i < files.Size(); i++)
|
for (int i = 0; i < numFiles; i++)
|
||||||
{
|
{
|
||||||
CFileItem &file = files[i];
|
UInt64 t = 0;
|
||||||
CArchiveFileTime fileTime;
|
if (v.Defined[i])
|
||||||
fileTime.dwLowDateTime = 0;
|
t = ReadUInt64();
|
||||||
fileTime.dwHighDateTime = 0;
|
v.Values.Add(t);
|
||||||
bool defined = boolVector[i];
|
|
||||||
if (defined)
|
|
||||||
{
|
|
||||||
fileTime.dwLowDateTime = ReadUInt32();
|
|
||||||
fileTime.dwHighDateTime = ReadUInt32();
|
|
||||||
}
|
|
||||||
switch(type)
|
|
||||||
{
|
|
||||||
case NID::kCreationTime:
|
|
||||||
file.IsCreationTimeDefined = defined;
|
|
||||||
if (defined)
|
|
||||||
file.CreationTime = fileTime;
|
|
||||||
break;
|
|
||||||
case NID::kLastWriteTime:
|
|
||||||
file.IsLastWriteTimeDefined = defined;
|
|
||||||
if (defined)
|
|
||||||
file.LastWriteTime = fileTime;
|
|
||||||
break;
|
|
||||||
case NID::kLastAccessTime:
|
|
||||||
file.IsLastAccessTimeDefined = defined;
|
|
||||||
if (defined)
|
|
||||||
file.LastAccessTime = fileTime;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CInArchive::ReadAndDecodePackedStreams(
|
HRESULT CInArchive::ReadAndDecodePackedStreams(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
UInt64 baseOffset,
|
UInt64 baseOffset,
|
||||||
UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
|
UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, ICryptoGetTextPassword *getTextPassword
|
, ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -719,23 +699,23 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
|||||||
CRecordVector<UInt32> packCRCs;
|
CRecordVector<UInt32> packCRCs;
|
||||||
CObjectVector<CFolder> folders;
|
CObjectVector<CFolder> folders;
|
||||||
|
|
||||||
CRecordVector<CNum> numUnPackStreamsInFolders;
|
CRecordVector<CNum> numUnpackStreamsInFolders;
|
||||||
CRecordVector<UInt64> unPackSizes;
|
CRecordVector<UInt64> unpackSizes;
|
||||||
CRecordVector<bool> digestsDefined;
|
CRecordVector<bool> digestsDefined;
|
||||||
CRecordVector<UInt32> digests;
|
CRecordVector<UInt32> digests;
|
||||||
|
|
||||||
ReadStreamsInfo(NULL,
|
ReadStreamsInfo(NULL,
|
||||||
dataOffset,
|
dataOffset,
|
||||||
packSizes,
|
packSizes,
|
||||||
packCRCsDefined,
|
packCRCsDefined,
|
||||||
packCRCs,
|
packCRCs,
|
||||||
folders,
|
folders,
|
||||||
numUnPackStreamsInFolders,
|
numUnpackStreamsInFolders,
|
||||||
unPackSizes,
|
unpackSizes,
|
||||||
digestsDefined,
|
digestsDefined,
|
||||||
digests);
|
digests);
|
||||||
|
|
||||||
// database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
|
// db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;
|
||||||
|
|
||||||
CNum packIndex = 0;
|
CNum packIndex = 0;
|
||||||
CDecoder decoder(
|
CDecoder decoder(
|
||||||
@@ -746,27 +726,27 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
|||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
UInt64 dataStartPos = baseOffset + dataOffset;
|
UInt64 dataStartPos = baseOffset + dataOffset;
|
||||||
for(int i = 0; i < folders.Size(); i++)
|
for (int i = 0; i < folders.Size(); i++)
|
||||||
{
|
{
|
||||||
const CFolder &folder = folders[i];
|
const CFolder &folder = folders[i];
|
||||||
dataVector.Add(CByteBuffer());
|
dataVector.Add(CByteBuffer());
|
||||||
CByteBuffer &data = dataVector.Back();
|
CByteBuffer &data = dataVector.Back();
|
||||||
UInt64 unPackSize64 = folder.GetUnPackSize();
|
UInt64 unpackSize64 = folder.GetUnpackSize();
|
||||||
size_t unPackSize = (size_t)unPackSize64;
|
size_t unpackSize = (size_t)unpackSize64;
|
||||||
if (unPackSize != unPackSize64)
|
if (unpackSize != unpackSize64)
|
||||||
ThrowUnsupported();
|
ThrowUnsupported();
|
||||||
data.SetCapacity(unPackSize);
|
data.SetCapacity(unpackSize);
|
||||||
|
|
||||||
CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2;
|
CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2;
|
||||||
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
|
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
|
||||||
outStreamSpec->Init(data, unPackSize);
|
outStreamSpec->Init(data, unpackSize);
|
||||||
|
|
||||||
HRESULT result = decoder.Decode(
|
HRESULT result = decoder.Decode(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
_stream, dataStartPos,
|
_stream, dataStartPos,
|
||||||
&packSizes[packIndex], folder, outStream, NULL
|
&packSizes[packIndex], folder, outStream, NULL
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, getTextPassword
|
, getTextPassword, passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
#ifdef COMPRESS_MT
|
#ifdef COMPRESS_MT
|
||||||
, false, 1
|
, false, 1
|
||||||
@@ -774,20 +754,24 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
|||||||
);
|
);
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
|
|
||||||
if (folder.UnPackCRCDefined)
|
if (folder.UnpackCRCDefined)
|
||||||
if (CrcCalc(data, unPackSize) != folder.UnPackCRC)
|
if (CrcCalc(data, unpackSize) != folder.UnpackCRC)
|
||||||
ThrowIncorrect();
|
ThrowIncorrect();
|
||||||
for (int j = 0; j < folder.PackStreams.Size(); j++)
|
for (int j = 0; j < folder.PackStreams.Size(); j++)
|
||||||
dataStartPos += packSizes[packIndex++];
|
{
|
||||||
|
UInt64 packSize = packSizes[packIndex++];
|
||||||
|
dataStartPos += packSize;
|
||||||
|
HeadersSize += packSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CInArchive::ReadHeader(
|
HRESULT CInArchive::ReadHeader(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
CArchiveDatabaseEx &database
|
CArchiveDatabaseEx &db
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, ICryptoGetTextPassword *getTextPassword
|
, ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -795,7 +779,7 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
|
|
||||||
if (type == NID::kArchiveProperties)
|
if (type == NID::kArchiveProperties)
|
||||||
{
|
{
|
||||||
ReadArchiveProperties(database.ArchiveInfo);
|
ReadArchiveProperties(db.ArchiveInfo);
|
||||||
type = ReadID();
|
type = ReadID();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -805,50 +789,50 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
{
|
{
|
||||||
HRESULT result = ReadAndDecodePackedStreams(
|
HRESULT result = ReadAndDecodePackedStreams(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
database.ArchiveInfo.StartPositionAfterHeader,
|
db.ArchiveInfo.StartPositionAfterHeader,
|
||||||
database.ArchiveInfo.DataStartPosition2,
|
db.ArchiveInfo.DataStartPosition2,
|
||||||
dataVector
|
dataVector
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, getTextPassword
|
, getTextPassword, passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
|
db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;
|
||||||
type = ReadID();
|
type = ReadID();
|
||||||
}
|
}
|
||||||
|
|
||||||
CRecordVector<UInt64> unPackSizes;
|
CRecordVector<UInt64> unpackSizes;
|
||||||
CRecordVector<bool> digestsDefined;
|
CRecordVector<bool> digestsDefined;
|
||||||
CRecordVector<UInt32> digests;
|
CRecordVector<UInt32> digests;
|
||||||
|
|
||||||
if (type == NID::kMainStreamsInfo)
|
if (type == NID::kMainStreamsInfo)
|
||||||
{
|
{
|
||||||
ReadStreamsInfo(&dataVector,
|
ReadStreamsInfo(&dataVector,
|
||||||
database.ArchiveInfo.DataStartPosition,
|
db.ArchiveInfo.DataStartPosition,
|
||||||
database.PackSizes,
|
db.PackSizes,
|
||||||
database.PackCRCsDefined,
|
db.PackCRCsDefined,
|
||||||
database.PackCRCs,
|
db.PackCRCs,
|
||||||
database.Folders,
|
db.Folders,
|
||||||
database.NumUnPackStreamsVector,
|
db.NumUnpackStreamsVector,
|
||||||
unPackSizes,
|
unpackSizes,
|
||||||
digestsDefined,
|
digestsDefined,
|
||||||
digests);
|
digests);
|
||||||
database.ArchiveInfo.DataStartPosition += database.ArchiveInfo.StartPositionAfterHeader;
|
db.ArchiveInfo.DataStartPosition += db.ArchiveInfo.StartPositionAfterHeader;
|
||||||
type = ReadID();
|
type = ReadID();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(int i = 0; i < database.Folders.Size(); i++)
|
for (int i = 0; i < db.Folders.Size(); i++)
|
||||||
{
|
{
|
||||||
database.NumUnPackStreamsVector.Add(1);
|
db.NumUnpackStreamsVector.Add(1);
|
||||||
CFolder &folder = database.Folders[i];
|
CFolder &folder = db.Folders[i];
|
||||||
unPackSizes.Add(folder.GetUnPackSize());
|
unpackSizes.Add(folder.GetUnpackSize());
|
||||||
digestsDefined.Add(folder.UnPackCRCDefined);
|
digestsDefined.Add(folder.UnpackCRCDefined);
|
||||||
digests.Add(folder.UnPackCRC);
|
digests.Add(folder.UnpackCRC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
database.Files.Clear();
|
db.Files.Clear();
|
||||||
|
|
||||||
if (type == NID::kEnd)
|
if (type == NID::kEnd)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@@ -856,20 +840,20 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
ThrowIncorrect();
|
ThrowIncorrect();
|
||||||
|
|
||||||
CNum numFiles = ReadNum();
|
CNum numFiles = ReadNum();
|
||||||
database.Files.Reserve(numFiles);
|
db.Files.Reserve(numFiles);
|
||||||
CNum i;
|
CNum i;
|
||||||
for(i = 0; i < numFiles; i++)
|
for (i = 0; i < numFiles; i++)
|
||||||
database.Files.Add(CFileItem());
|
db.Files.Add(CFileItem());
|
||||||
|
|
||||||
database.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);
|
db.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);
|
||||||
if (!database.PackSizes.IsEmpty())
|
if (!db.PackSizes.IsEmpty())
|
||||||
database.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);
|
db.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);
|
||||||
if (numFiles > 0 && !digests.IsEmpty())
|
if (numFiles > 0 && !digests.IsEmpty())
|
||||||
database.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
|
db.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
|
||||||
|
|
||||||
CBoolVector emptyStreamVector;
|
CBoolVector emptyStreamVector;
|
||||||
emptyStreamVector.Reserve((int)numFiles);
|
emptyStreamVector.Reserve((int)numFiles);
|
||||||
for(i = 0; i < numFiles; i++)
|
for (i = 0; i < numFiles; i++)
|
||||||
emptyStreamVector.Add(false);
|
emptyStreamVector.Add(false);
|
||||||
CBoolVector emptyFileVector;
|
CBoolVector emptyFileVector;
|
||||||
CBoolVector antiFileVector;
|
CBoolVector antiFileVector;
|
||||||
@@ -881,6 +865,8 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
if (type == NID::kEnd)
|
if (type == NID::kEnd)
|
||||||
break;
|
break;
|
||||||
UInt64 size = ReadNumber();
|
UInt64 size = ReadNumber();
|
||||||
|
size_t ppp = _inByteBack->_pos;
|
||||||
|
bool addPropIdToList = true;
|
||||||
bool isKnownType = true;
|
bool isKnownType = true;
|
||||||
if (type > ((UInt32)1 << 30))
|
if (type > ((UInt32)1 << 30))
|
||||||
isKnownType = false;
|
isKnownType = false;
|
||||||
@@ -890,37 +876,22 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
{
|
{
|
||||||
CStreamSwitch streamSwitch;
|
CStreamSwitch streamSwitch;
|
||||||
streamSwitch.Set(this, &dataVector);
|
streamSwitch.Set(this, &dataVector);
|
||||||
for(int i = 0; i < database.Files.Size(); i++)
|
for (int i = 0; i < db.Files.Size(); i++)
|
||||||
_inByteBack->ReadString(database.Files[i].Name);
|
_inByteBack->ReadString(db.Files[i].Name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NID::kWinAttributes:
|
case NID::kWinAttributes:
|
||||||
{
|
{
|
||||||
CBoolVector boolVector;
|
CBoolVector boolVector;
|
||||||
ReadBoolVector2(database.Files.Size(), boolVector);
|
ReadBoolVector2(db.Files.Size(), boolVector);
|
||||||
CStreamSwitch streamSwitch;
|
CStreamSwitch streamSwitch;
|
||||||
streamSwitch.Set(this, &dataVector);
|
streamSwitch.Set(this, &dataVector);
|
||||||
for(i = 0; i < numFiles; i++)
|
for (i = 0; i < numFiles; i++)
|
||||||
{
|
{
|
||||||
CFileItem &file = database.Files[i];
|
CFileItem &file = db.Files[i];
|
||||||
file.AreAttributesDefined = boolVector[i];
|
file.AttribDefined = boolVector[i];
|
||||||
if (file.AreAttributesDefined)
|
if (file.AttribDefined)
|
||||||
file.Attributes = ReadUInt32();
|
file.Attrib = ReadUInt32();
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NID::kStartPos:
|
|
||||||
{
|
|
||||||
CBoolVector boolVector;
|
|
||||||
ReadBoolVector2(database.Files.Size(), boolVector);
|
|
||||||
CStreamSwitch streamSwitch;
|
|
||||||
streamSwitch.Set(this, &dataVector);
|
|
||||||
for(i = 0; i < numFiles; i++)
|
|
||||||
{
|
|
||||||
CFileItem &file = database.Files[i];
|
|
||||||
file.IsStartPosDefined = boolVector[i];
|
|
||||||
if (file.IsStartPosDefined)
|
|
||||||
file.StartPos = ReadUInt64();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -939,55 +910,68 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NID::kEmptyFile:
|
case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break;
|
||||||
|
case NID::kAnti: ReadBoolVector(numEmptyStreams, antiFileVector); break;
|
||||||
|
case NID::kStartPos: ReadUInt64DefVector(dataVector, db.StartPos, (int)numFiles); break;
|
||||||
|
case NID::kCTime: ReadUInt64DefVector(dataVector, db.CTime, (int)numFiles); break;
|
||||||
|
case NID::kATime: ReadUInt64DefVector(dataVector, db.ATime, (int)numFiles); break;
|
||||||
|
case NID::kMTime: ReadUInt64DefVector(dataVector, db.MTime, (int)numFiles); break;
|
||||||
|
case NID::kDummy:
|
||||||
{
|
{
|
||||||
ReadBoolVector(numEmptyStreams, emptyFileVector);
|
for (UInt64 j = 0; j < size; j++)
|
||||||
break;
|
if (ReadByte() != 0)
|
||||||
}
|
ThrowIncorrect();
|
||||||
case NID::kAnti:
|
addPropIdToList = false;
|
||||||
{
|
|
||||||
ReadBoolVector(numEmptyStreams, antiFileVector);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NID::kCreationTime:
|
|
||||||
case NID::kLastWriteTime:
|
|
||||||
case NID::kLastAccessTime:
|
|
||||||
{
|
|
||||||
ReadTime(dataVector, database.Files, (UInt32)type);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
isKnownType = false;
|
addPropIdToList = isKnownType = false;
|
||||||
}
|
}
|
||||||
if (isKnownType)
|
if (isKnownType)
|
||||||
database.ArchiveInfo.FileInfoPopIDs.Add(type);
|
{
|
||||||
|
if(addPropIdToList)
|
||||||
|
db.ArchiveInfo.FileInfoPopIDs.Add(type);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
SkeepData(size);
|
SkeepData(size);
|
||||||
|
bool checkRecordsSize = (db.ArchiveInfo.Version.Major > 0 ||
|
||||||
|
db.ArchiveInfo.Version.Minor > 2);
|
||||||
|
if (checkRecordsSize && _inByteBack->_pos - ppp != size)
|
||||||
|
ThrowIncorrect();
|
||||||
}
|
}
|
||||||
|
|
||||||
CNum emptyFileIndex = 0;
|
CNum emptyFileIndex = 0;
|
||||||
CNum sizeIndex = 0;
|
CNum sizeIndex = 0;
|
||||||
for(i = 0; i < numFiles; i++)
|
|
||||||
|
CNum numAntiItems = 0;
|
||||||
|
for (i = 0; i < numEmptyStreams; i++)
|
||||||
|
if (antiFileVector[i])
|
||||||
|
numAntiItems++;
|
||||||
|
|
||||||
|
for (i = 0; i < numFiles; i++)
|
||||||
{
|
{
|
||||||
CFileItem &file = database.Files[i];
|
CFileItem &file = db.Files[i];
|
||||||
|
bool isAnti;
|
||||||
file.HasStream = !emptyStreamVector[i];
|
file.HasStream = !emptyStreamVector[i];
|
||||||
if(file.HasStream)
|
if (file.HasStream)
|
||||||
{
|
{
|
||||||
file.IsDirectory = false;
|
file.IsDir = false;
|
||||||
file.IsAnti = false;
|
isAnti = false;
|
||||||
file.UnPackSize = unPackSizes[sizeIndex];
|
file.Size = unpackSizes[sizeIndex];
|
||||||
file.FileCRC = digests[sizeIndex];
|
file.Crc = digests[sizeIndex];
|
||||||
file.IsFileCRCDefined = digestsDefined[sizeIndex];
|
file.CrcDefined = digestsDefined[sizeIndex];
|
||||||
sizeIndex++;
|
sizeIndex++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
file.IsDirectory = !emptyFileVector[emptyFileIndex];
|
file.IsDir = !emptyFileVector[emptyFileIndex];
|
||||||
file.IsAnti = antiFileVector[emptyFileIndex];
|
isAnti = antiFileVector[emptyFileIndex];
|
||||||
emptyFileIndex++;
|
emptyFileIndex++;
|
||||||
file.UnPackSize = 0;
|
file.Size = 0;
|
||||||
file.IsFileCRCDefined = false;
|
file.CrcDefined = false;
|
||||||
}
|
}
|
||||||
|
if (numAntiItems != 0)
|
||||||
|
db.IsAnti.Add(isAnti);
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -998,7 +982,7 @@ void CArchiveDatabaseEx::FillFolderStartPackStream()
|
|||||||
FolderStartPackStreamIndex.Clear();
|
FolderStartPackStreamIndex.Clear();
|
||||||
FolderStartPackStreamIndex.Reserve(Folders.Size());
|
FolderStartPackStreamIndex.Reserve(Folders.Size());
|
||||||
CNum startPos = 0;
|
CNum startPos = 0;
|
||||||
for(int i = 0; i < Folders.Size(); i++)
|
for (int i = 0; i < Folders.Size(); i++)
|
||||||
{
|
{
|
||||||
FolderStartPackStreamIndex.Add(startPos);
|
FolderStartPackStreamIndex.Add(startPos);
|
||||||
startPos += (CNum)Folders[i].PackStreams.Size();
|
startPos += (CNum)Folders[i].PackStreams.Size();
|
||||||
@@ -1010,7 +994,7 @@ void CArchiveDatabaseEx::FillStartPos()
|
|||||||
PackStreamStartPositions.Clear();
|
PackStreamStartPositions.Clear();
|
||||||
PackStreamStartPositions.Reserve(PackSizes.Size());
|
PackStreamStartPositions.Reserve(PackSizes.Size());
|
||||||
UInt64 startPos = 0;
|
UInt64 startPos = 0;
|
||||||
for(int i = 0; i < PackSizes.Size(); i++)
|
for (int i = 0; i < PackSizes.Size(); i++)
|
||||||
{
|
{
|
||||||
PackStreamStartPositions.Add(startPos);
|
PackStreamStartPositions.Add(startPos);
|
||||||
startPos += PackSizes[i];
|
startPos += PackSizes[i];
|
||||||
@@ -1044,7 +1028,7 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex()
|
|||||||
if (folderIndex >= Folders.Size())
|
if (folderIndex >= Folders.Size())
|
||||||
ThrowIncorrect();
|
ThrowIncorrect();
|
||||||
FolderStartFileIndex.Add(i); // check it
|
FolderStartFileIndex.Add(i); // check it
|
||||||
if (NumUnPackStreamsVector[folderIndex] != 0)
|
if (NumUnpackStreamsVector[folderIndex] != 0)
|
||||||
break;
|
break;
|
||||||
folderIndex++;
|
folderIndex++;
|
||||||
}
|
}
|
||||||
@@ -1053,7 +1037,7 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex()
|
|||||||
if (emptyStream)
|
if (emptyStream)
|
||||||
continue;
|
continue;
|
||||||
indexInFolder++;
|
indexInFolder++;
|
||||||
if (indexInFolder >= NumUnPackStreamsVector[folderIndex])
|
if (indexInFolder >= NumUnpackStreamsVector[folderIndex])
|
||||||
{
|
{
|
||||||
folderIndex++;
|
folderIndex++;
|
||||||
indexInFolder = 0;
|
indexInFolder = 0;
|
||||||
@@ -1063,25 +1047,25 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex()
|
|||||||
|
|
||||||
HRESULT CInArchive::ReadDatabase2(
|
HRESULT CInArchive::ReadDatabase2(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
CArchiveDatabaseEx &database
|
CArchiveDatabaseEx &db
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, ICryptoGetTextPassword *getTextPassword
|
, ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
database.Clear();
|
db.Clear();
|
||||||
database.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
|
db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
|
||||||
|
|
||||||
database.ArchiveInfo.Version.Major = _header[6];
|
db.ArchiveInfo.Version.Major = _header[6];
|
||||||
database.ArchiveInfo.Version.Minor = _header[7];
|
db.ArchiveInfo.Version.Minor = _header[7];
|
||||||
|
|
||||||
if (database.ArchiveInfo.Version.Major != kMajorVersion)
|
if (db.ArchiveInfo.Version.Major != kMajorVersion)
|
||||||
ThrowUnsupportedVersion();
|
ThrowUnsupportedVersion();
|
||||||
|
|
||||||
UInt32 crcFromArchive = GetUInt32FromMem(_header + 8);
|
UInt32 crcFromArchive = Get32(_header + 8);
|
||||||
UInt64 nextHeaderOffset = GetUInt64FromMem(_header + 0xC);
|
UInt64 nextHeaderOffset = Get64(_header + 0xC);
|
||||||
UInt64 nextHeaderSize = GetUInt64FromMem(_header + 0x14);
|
UInt64 nextHeaderSize = Get64(_header + 0x14);
|
||||||
UInt32 nextHeaderCRC = GetUInt32FromMem(_header + 0x1C);
|
UInt32 nextHeaderCRC = Get32(_header + 0x1C);
|
||||||
UInt32 crc = CrcCalc(_header + 0xC, 20);
|
UInt32 crc = CrcCalc(_header + 0xC, 20);
|
||||||
|
|
||||||
#ifdef FORMAT_7Z_RECOVERY
|
#ifdef FORMAT_7Z_RECOVERY
|
||||||
@@ -1097,16 +1081,15 @@ HRESULT CInArchive::ReadDatabase2(
|
|||||||
checkSize = (int)(cur2 - cur);
|
checkSize = (int)(cur2 - cur);
|
||||||
RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2));
|
RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2));
|
||||||
|
|
||||||
UInt32 realProcessedSize;
|
RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize));
|
||||||
RINOK(_stream->Read(buf, (UInt32)kCheckSize, &realProcessedSize));
|
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = (int)realProcessedSize - 2; i >= 0; i--)
|
for (i = (int)checkSize - 2; i >= 0; i--)
|
||||||
if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04)
|
if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04)
|
||||||
break;
|
break;
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
nextHeaderSize = realProcessedSize - i;
|
nextHeaderSize = checkSize - i;
|
||||||
nextHeaderOffset = cur2 - cur + i;
|
nextHeaderOffset = cur2 - cur + i;
|
||||||
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));
|
||||||
@@ -1117,7 +1100,7 @@ HRESULT CInArchive::ReadDatabase2(
|
|||||||
crcFromArchive = crc;
|
crcFromArchive = crc;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
database.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
|
db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
|
||||||
|
|
||||||
if (crc != crcFromArchive)
|
if (crc != crcFromArchive)
|
||||||
ThrowIncorrect();
|
ThrowIncorrect();
|
||||||
@@ -1133,10 +1116,10 @@ HRESULT CInArchive::ReadDatabase2(
|
|||||||
CByteBuffer buffer2;
|
CByteBuffer buffer2;
|
||||||
buffer2.SetCapacity((size_t)nextHeaderSize);
|
buffer2.SetCapacity((size_t)nextHeaderSize);
|
||||||
|
|
||||||
UInt32 realProcessedSize;
|
RINOK(ReadStream_FALSE(_stream, buffer2, (size_t)nextHeaderSize));
|
||||||
RINOK(_stream->Read(buffer2, (UInt32)nextHeaderSize, &realProcessedSize));
|
HeadersSize += kHeaderSize + nextHeaderSize;
|
||||||
if (realProcessedSize != (UInt32)nextHeaderSize)
|
db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize;
|
||||||
return S_FALSE;
|
|
||||||
if (CrcCalc(buffer2, (UInt32)nextHeaderSize) != nextHeaderCRC)
|
if (CrcCalc(buffer2, (UInt32)nextHeaderSize) != nextHeaderCRC)
|
||||||
ThrowIncorrect();
|
ThrowIncorrect();
|
||||||
|
|
||||||
@@ -1145,20 +1128,18 @@ HRESULT CInArchive::ReadDatabase2(
|
|||||||
|
|
||||||
CObjectVector<CByteBuffer> dataVector;
|
CObjectVector<CByteBuffer> dataVector;
|
||||||
|
|
||||||
for (;;)
|
UInt64 type = ReadID();
|
||||||
|
if (type != NID::kHeader)
|
||||||
{
|
{
|
||||||
UInt64 type = ReadID();
|
|
||||||
if (type == NID::kHeader)
|
|
||||||
break;
|
|
||||||
if (type != NID::kEncodedHeader)
|
if (type != NID::kEncodedHeader)
|
||||||
ThrowIncorrect();
|
ThrowIncorrect();
|
||||||
HRESULT result = ReadAndDecodePackedStreams(
|
HRESULT result = ReadAndDecodePackedStreams(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
database.ArchiveInfo.StartPositionAfterHeader,
|
db.ArchiveInfo.StartPositionAfterHeader,
|
||||||
database.ArchiveInfo.DataStartPosition2,
|
db.ArchiveInfo.DataStartPosition2,
|
||||||
dataVector
|
dataVector
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, getTextPassword
|
, getTextPassword, passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
@@ -1168,31 +1149,35 @@ HRESULT CInArchive::ReadDatabase2(
|
|||||||
ThrowIncorrect();
|
ThrowIncorrect();
|
||||||
streamSwitch.Remove();
|
streamSwitch.Remove();
|
||||||
streamSwitch.Set(this, dataVector.Front());
|
streamSwitch.Set(this, dataVector.Front());
|
||||||
|
if (ReadID() != NID::kHeader)
|
||||||
|
ThrowIncorrect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db.HeadersSize = HeadersSize;
|
||||||
|
|
||||||
return ReadHeader(
|
return ReadHeader(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
database
|
db
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, getTextPassword
|
, getTextPassword, passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CInArchive::ReadDatabase(
|
HRESULT CInArchive::ReadDatabase(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
CArchiveDatabaseEx &database
|
CArchiveDatabaseEx &db
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, ICryptoGetTextPassword *getTextPassword
|
, ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return ReadDatabase2(
|
return ReadDatabase2(
|
||||||
EXTERNAL_CODECS_LOC_VARS database
|
EXTERNAL_CODECS_LOC_VARS db
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, getTextPassword
|
, getTextPassword, passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-19
@@ -36,6 +36,9 @@ struct CArchiveDatabaseEx: public CArchiveDatabase
|
|||||||
CRecordVector<CNum> FolderStartFileIndex;
|
CRecordVector<CNum> FolderStartFileIndex;
|
||||||
CRecordVector<CNum> FileIndexToFolderIndexMap;
|
CRecordVector<CNum> FileIndexToFolderIndexMap;
|
||||||
|
|
||||||
|
UInt64 HeadersSize;
|
||||||
|
UInt64 PhySize;
|
||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
CArchiveDatabase::Clear();
|
CArchiveDatabase::Clear();
|
||||||
@@ -44,6 +47,9 @@ struct CArchiveDatabaseEx: public CArchiveDatabase
|
|||||||
FolderStartPackStreamIndex.Clear();
|
FolderStartPackStreamIndex.Clear();
|
||||||
FolderStartFileIndex.Clear();
|
FolderStartFileIndex.Clear();
|
||||||
FileIndexToFolderIndexMap.Clear();
|
FileIndexToFolderIndexMap.Clear();
|
||||||
|
|
||||||
|
HeadersSize = 0;
|
||||||
|
PhySize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FillFolderStartPackStream();
|
void FillFolderStartPackStream();
|
||||||
@@ -63,7 +69,7 @@ struct CArchiveDatabaseEx: public CArchiveDatabase
|
|||||||
PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + indexInFolder];
|
PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + indexInFolder];
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt64 GetFolderFullPackSize(int folderIndex) const
|
UInt64 GetFolderFullPackSize(int folderIndex) const
|
||||||
{
|
{
|
||||||
CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex];
|
CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex];
|
||||||
const CFolder &folder = Folders[folderIndex];
|
const CFolder &folder = Folders[folderIndex];
|
||||||
@@ -73,7 +79,7 @@ struct CArchiveDatabaseEx: public CArchiveDatabase
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
|
UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
|
||||||
{
|
{
|
||||||
return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
|
return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
|
||||||
}
|
}
|
||||||
@@ -92,8 +98,8 @@ class CInByte2
|
|||||||
{
|
{
|
||||||
const Byte *_buffer;
|
const Byte *_buffer;
|
||||||
size_t _size;
|
size_t _size;
|
||||||
size_t _pos;
|
|
||||||
public:
|
public:
|
||||||
|
size_t _pos;
|
||||||
void Init(const Byte *buffer, size_t size)
|
void Init(const Byte *buffer, size_t size)
|
||||||
{
|
{
|
||||||
_buffer = buffer;
|
_buffer = buffer;
|
||||||
@@ -128,6 +134,8 @@ class CInArchive
|
|||||||
|
|
||||||
Byte _header[kHeaderSize];
|
Byte _header[kHeaderSize];
|
||||||
|
|
||||||
|
UInt64 HeadersSize;
|
||||||
|
|
||||||
void AddByteStream(const Byte *buffer, size_t size)
|
void AddByteStream(const Byte *buffer, size_t size)
|
||||||
{
|
{
|
||||||
_inByteVector.Add(CInByte2());
|
_inByteVector.Add(CInByte2());
|
||||||
@@ -167,15 +175,15 @@ private:
|
|||||||
CRecordVector<bool> &packCRCsDefined,
|
CRecordVector<bool> &packCRCsDefined,
|
||||||
CRecordVector<UInt32> &packCRCs);
|
CRecordVector<UInt32> &packCRCs);
|
||||||
|
|
||||||
void ReadUnPackInfo(
|
void ReadUnpackInfo(
|
||||||
const CObjectVector<CByteBuffer> *dataVector,
|
const CObjectVector<CByteBuffer> *dataVector,
|
||||||
CObjectVector<CFolder> &folders);
|
CObjectVector<CFolder> &folders);
|
||||||
|
|
||||||
void ReadSubStreamsInfo(
|
void ReadSubStreamsInfo(
|
||||||
const CObjectVector<CFolder> &folders,
|
const CObjectVector<CFolder> &folders,
|
||||||
CRecordVector<CNum> &numUnPackStreamsInFolders,
|
CRecordVector<CNum> &numUnpackStreamsInFolders,
|
||||||
CRecordVector<UInt64> &unPackSizes,
|
CRecordVector<UInt64> &unpackSizes,
|
||||||
CRecordVector<bool> &digestsDefined,
|
CRecordVector<bool> &digestsDefined,
|
||||||
CRecordVector<UInt32> &digests);
|
CRecordVector<UInt32> &digests);
|
||||||
|
|
||||||
void ReadStreamsInfo(
|
void ReadStreamsInfo(
|
||||||
@@ -185,36 +193,36 @@ private:
|
|||||||
CRecordVector<bool> &packCRCsDefined,
|
CRecordVector<bool> &packCRCsDefined,
|
||||||
CRecordVector<UInt32> &packCRCs,
|
CRecordVector<UInt32> &packCRCs,
|
||||||
CObjectVector<CFolder> &folders,
|
CObjectVector<CFolder> &folders,
|
||||||
CRecordVector<CNum> &numUnPackStreamsInFolders,
|
CRecordVector<CNum> &numUnpackStreamsInFolders,
|
||||||
CRecordVector<UInt64> &unPackSizes,
|
CRecordVector<UInt64> &unpackSizes,
|
||||||
CRecordVector<bool> &digestsDefined,
|
CRecordVector<bool> &digestsDefined,
|
||||||
CRecordVector<UInt32> &digests);
|
CRecordVector<UInt32> &digests);
|
||||||
|
|
||||||
|
|
||||||
void ReadBoolVector(int numItems, CBoolVector &v);
|
void ReadBoolVector(int numItems, CBoolVector &v);
|
||||||
void ReadBoolVector2(int numItems, CBoolVector &v);
|
void ReadBoolVector2(int numItems, CBoolVector &v);
|
||||||
void ReadTime(const CObjectVector<CByteBuffer> &dataVector,
|
void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
|
||||||
CObjectVector<CFileItem> &files, UInt32 type);
|
CUInt64DefVector &v, int numFiles);
|
||||||
HRESULT ReadAndDecodePackedStreams(
|
HRESULT ReadAndDecodePackedStreams(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
UInt64 baseOffset, UInt64 &dataOffset,
|
UInt64 baseOffset, UInt64 &dataOffset,
|
||||||
CObjectVector<CByteBuffer> &dataVector
|
CObjectVector<CByteBuffer> &dataVector
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, ICryptoGetTextPassword *getTextPassword
|
, ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
HRESULT ReadHeader(
|
HRESULT ReadHeader(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
CArchiveDatabaseEx &database
|
CArchiveDatabaseEx &db
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
,ICryptoGetTextPassword *getTextPassword
|
,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
HRESULT ReadDatabase2(
|
HRESULT ReadDatabase2(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
CArchiveDatabaseEx &database
|
CArchiveDatabaseEx &db
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
,ICryptoGetTextPassword *getTextPassword
|
,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
public:
|
public:
|
||||||
@@ -223,9 +231,9 @@ public:
|
|||||||
|
|
||||||
HRESULT ReadDatabase(
|
HRESULT ReadDatabase(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
CArchiveDatabaseEx &database
|
CArchiveDatabaseEx &db
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
,ICryptoGetTextPassword *getTextPassword
|
,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
+139
-69
@@ -35,19 +35,19 @@ struct CFolder
|
|||||||
CObjectVector<CCoderInfo> Coders;
|
CObjectVector<CCoderInfo> Coders;
|
||||||
CRecordVector<CBindPair> BindPairs;
|
CRecordVector<CBindPair> BindPairs;
|
||||||
CRecordVector<CNum> PackStreams;
|
CRecordVector<CNum> PackStreams;
|
||||||
CRecordVector<UInt64> UnPackSizes;
|
CRecordVector<UInt64> UnpackSizes;
|
||||||
UInt32 UnPackCRC;
|
UInt32 UnpackCRC;
|
||||||
bool UnPackCRCDefined;
|
bool UnpackCRCDefined;
|
||||||
|
|
||||||
CFolder(): UnPackCRCDefined(false) {}
|
CFolder(): UnpackCRCDefined(false) {}
|
||||||
|
|
||||||
UInt64 GetUnPackSize() const // test it
|
UInt64 GetUnpackSize() const // test it
|
||||||
{
|
{
|
||||||
if (UnPackSizes.IsEmpty())
|
if (UnpackSizes.IsEmpty())
|
||||||
return 0;
|
return 0;
|
||||||
for (int i = UnPackSizes.Size() - 1; i >= 0; i--)
|
for (int i = UnpackSizes.Size() - 1; i >= 0; i--)
|
||||||
if (FindBindPairForOutStream(i) < 0)
|
if (FindBindPairForOutStream(i) < 0)
|
||||||
return UnPackSizes[i];
|
return UnpackSizes[i];
|
||||||
throw 1;
|
throw 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,101 +82,171 @@ struct CFolder
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef FILETIME CArchiveFileTime;
|
struct CUInt64DefVector
|
||||||
|
|
||||||
class CFileItem
|
|
||||||
{
|
{
|
||||||
public:
|
CRecordVector<UInt64> Values;
|
||||||
CArchiveFileTime CreationTime;
|
CRecordVector<bool> Defined;
|
||||||
CArchiveFileTime LastWriteTime;
|
|
||||||
CArchiveFileTime LastAccessTime;
|
void Clear()
|
||||||
UInt64 UnPackSize;
|
{
|
||||||
UInt64 StartPos;
|
Values.Clear();
|
||||||
UInt32 Attributes;
|
Defined.Clear();
|
||||||
UInt32 FileCRC;
|
}
|
||||||
|
|
||||||
|
void ReserveDown()
|
||||||
|
{
|
||||||
|
Values.ReserveDown();
|
||||||
|
Values.ReserveDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetItem(int index, UInt64 &value) const
|
||||||
|
{
|
||||||
|
if (index < Defined.Size() && Defined[index])
|
||||||
|
{
|
||||||
|
value = Values[index];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
value = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetItem(int index, bool defined, UInt64 value)
|
||||||
|
{
|
||||||
|
while (index >= Defined.Size())
|
||||||
|
Defined.Add(false);
|
||||||
|
Defined[index] = defined;
|
||||||
|
if (!defined)
|
||||||
|
return;
|
||||||
|
while (index >= Values.Size())
|
||||||
|
Values.Add(0);
|
||||||
|
Values[index] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckSize(int size) const { return Defined.Size() == size || Defined.Size() == 0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CFileItem
|
||||||
|
{
|
||||||
|
UInt64 Size;
|
||||||
|
UInt32 Attrib;
|
||||||
|
UInt32 Crc;
|
||||||
UString Name;
|
UString Name;
|
||||||
|
|
||||||
bool HasStream; // Test it !!! it means that there is
|
bool HasStream; // Test it !!! it means that there is
|
||||||
// stream in some folder. It can be empty stream
|
// stream in some folder. It can be empty stream
|
||||||
bool IsDirectory;
|
bool IsDir;
|
||||||
bool IsAnti;
|
bool CrcDefined;
|
||||||
bool IsFileCRCDefined;
|
bool AttribDefined;
|
||||||
bool AreAttributesDefined;
|
|
||||||
bool IsCreationTimeDefined;
|
|
||||||
bool IsLastWriteTimeDefined;
|
|
||||||
bool IsLastAccessTimeDefined;
|
|
||||||
bool IsStartPosDefined;
|
|
||||||
|
|
||||||
/*
|
CFileItem():
|
||||||
const bool HasStream() const {
|
|
||||||
return !IsDirectory && !IsAnti && UnPackSize != 0; }
|
|
||||||
*/
|
|
||||||
CFileItem():
|
|
||||||
HasStream(true),
|
HasStream(true),
|
||||||
IsDirectory(false),
|
IsDir(false),
|
||||||
IsAnti(false),
|
CrcDefined(false),
|
||||||
IsFileCRCDefined(false),
|
AttribDefined(false)
|
||||||
AreAttributesDefined(false),
|
|
||||||
IsCreationTimeDefined(false),
|
|
||||||
IsLastWriteTimeDefined(false),
|
|
||||||
IsLastAccessTimeDefined(false),
|
|
||||||
IsStartPosDefined(false)
|
|
||||||
{}
|
{}
|
||||||
void SetAttributes(UInt32 attributes)
|
void SetAttrib(UInt32 attrib)
|
||||||
{
|
|
||||||
AreAttributesDefined = true;
|
|
||||||
Attributes = attributes;
|
|
||||||
}
|
|
||||||
void SetCreationTime(const CArchiveFileTime &creationTime)
|
|
||||||
{
|
|
||||||
IsCreationTimeDefined = true;
|
|
||||||
CreationTime = creationTime;
|
|
||||||
}
|
|
||||||
void SetLastWriteTime(const CArchiveFileTime &lastWriteTime)
|
|
||||||
{
|
{
|
||||||
IsLastWriteTimeDefined = true;
|
AttribDefined = true;
|
||||||
LastWriteTime = lastWriteTime;
|
Attrib = attrib;
|
||||||
}
|
|
||||||
void SetLastAccessTime(const CArchiveFileTime &lastAccessTime)
|
|
||||||
{
|
|
||||||
IsLastAccessTimeDefined = true;
|
|
||||||
LastAccessTime = lastAccessTime;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CFileItem2
|
||||||
|
{
|
||||||
|
UInt64 CTime;
|
||||||
|
UInt64 ATime;
|
||||||
|
UInt64 MTime;
|
||||||
|
UInt64 StartPos;
|
||||||
|
bool CTimeDefined;
|
||||||
|
bool ATimeDefined;
|
||||||
|
bool MTimeDefined;
|
||||||
|
bool StartPosDefined;
|
||||||
|
bool IsAnti;
|
||||||
|
};
|
||||||
|
|
||||||
struct CArchiveDatabase
|
struct CArchiveDatabase
|
||||||
{
|
{
|
||||||
CRecordVector<UInt64> PackSizes;
|
CRecordVector<UInt64> PackSizes;
|
||||||
CRecordVector<bool> PackCRCsDefined;
|
CRecordVector<bool> PackCRCsDefined;
|
||||||
CRecordVector<UInt32> PackCRCs;
|
CRecordVector<UInt32> PackCRCs;
|
||||||
CObjectVector<CFolder> Folders;
|
CObjectVector<CFolder> Folders;
|
||||||
CRecordVector<CNum> NumUnPackStreamsVector;
|
CRecordVector<CNum> NumUnpackStreamsVector;
|
||||||
CObjectVector<CFileItem> Files;
|
CObjectVector<CFileItem> Files;
|
||||||
|
|
||||||
|
CUInt64DefVector CTime;
|
||||||
|
CUInt64DefVector ATime;
|
||||||
|
CUInt64DefVector MTime;
|
||||||
|
CUInt64DefVector StartPos;
|
||||||
|
CRecordVector<bool> IsAnti;
|
||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
PackSizes.Clear();
|
PackSizes.Clear();
|
||||||
PackCRCsDefined.Clear();
|
PackCRCsDefined.Clear();
|
||||||
PackCRCs.Clear();
|
PackCRCs.Clear();
|
||||||
Folders.Clear();
|
Folders.Clear();
|
||||||
NumUnPackStreamsVector.Clear();
|
NumUnpackStreamsVector.Clear();
|
||||||
Files.Clear();
|
Files.Clear();
|
||||||
|
CTime.Clear();
|
||||||
|
ATime.Clear();
|
||||||
|
MTime.Clear();
|
||||||
|
StartPos.Clear();
|
||||||
|
IsAnti.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ReserveDown()
|
||||||
|
{
|
||||||
|
PackSizes.ReserveDown();
|
||||||
|
PackCRCsDefined.ReserveDown();
|
||||||
|
PackCRCs.ReserveDown();
|
||||||
|
Folders.ReserveDown();
|
||||||
|
NumUnpackStreamsVector.ReserveDown();
|
||||||
|
Files.ReserveDown();
|
||||||
|
CTime.ReserveDown();
|
||||||
|
ATime.ReserveDown();
|
||||||
|
MTime.ReserveDown();
|
||||||
|
StartPos.ReserveDown();
|
||||||
|
IsAnti.ReserveDown();
|
||||||
|
}
|
||||||
|
|
||||||
bool IsEmpty() const
|
bool IsEmpty() const
|
||||||
{
|
{
|
||||||
return (PackSizes.IsEmpty() &&
|
return (PackSizes.IsEmpty() &&
|
||||||
PackCRCsDefined.IsEmpty() &&
|
PackCRCsDefined.IsEmpty() &&
|
||||||
PackCRCs.IsEmpty() &&
|
PackCRCs.IsEmpty() &&
|
||||||
Folders.IsEmpty() &&
|
Folders.IsEmpty() &&
|
||||||
NumUnPackStreamsVector.IsEmpty() &&
|
NumUnpackStreamsVector.IsEmpty() &&
|
||||||
Files.IsEmpty());
|
Files.IsEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CheckNumFiles() const
|
||||||
|
{
|
||||||
|
int size = Files.Size();
|
||||||
|
return (
|
||||||
|
CTime.CheckSize(size) &&
|
||||||
|
ATime.CheckSize(size) &&
|
||||||
|
MTime.CheckSize(size) &&
|
||||||
|
StartPos.CheckSize(size) &&
|
||||||
|
(size == IsAnti.Size() || IsAnti.Size() == 0));
|
||||||
|
}
|
||||||
|
|
||||||
bool IsSolid() const
|
bool IsSolid() const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NumUnPackStreamsVector.Size(); i++)
|
for (int i = 0; i < NumUnpackStreamsVector.Size(); i++)
|
||||||
if (NumUnPackStreamsVector[i] > 1)
|
if (NumUnpackStreamsVector[i] > 1)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool IsItemAnti(int index) const { return (index < IsAnti.Size() && IsAnti[index]); }
|
||||||
|
void SetItemAnti(int index, bool isAnti)
|
||||||
|
{
|
||||||
|
while (index >= IsAnti.Size())
|
||||||
|
IsAnti.Add(false);
|
||||||
|
IsAnti[index] = isAnti;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetFile(int index, CFileItem &file, CFileItem2 &file2) const;
|
||||||
|
void AddFile(const CFileItem &file, const CFileItem2 &file2);
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
+364
-514
File diff suppressed because it is too large
Load Diff
+48
-85
@@ -9,7 +9,6 @@
|
|||||||
#include "7zEncode.h"
|
#include "7zEncode.h"
|
||||||
|
|
||||||
#include "../../Common/OutBuffer.h"
|
#include "../../Common/OutBuffer.h"
|
||||||
#include "../../../Common/DynamicBuffer.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
@@ -21,58 +20,41 @@ class CWriteBufferLoc
|
|||||||
size_t _pos;
|
size_t _pos;
|
||||||
public:
|
public:
|
||||||
CWriteBufferLoc(): _size(0), _pos(0) {}
|
CWriteBufferLoc(): _size(0), _pos(0) {}
|
||||||
void Init(Byte *data, size_t size)
|
void Init(Byte *data, size_t size)
|
||||||
{
|
{
|
||||||
_pos = 0;
|
|
||||||
_data = data;
|
_data = data;
|
||||||
_size = size;
|
_size = size;
|
||||||
}
|
|
||||||
HRESULT Write(const void *data, size_t size)
|
|
||||||
{
|
|
||||||
if (_pos + size > _size)
|
|
||||||
return E_FAIL;
|
|
||||||
memmove(_data + _pos, data, size);
|
|
||||||
_pos += size;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CWriteDynamicBuffer
|
|
||||||
{
|
|
||||||
CByteDynamicBuffer _buffer;
|
|
||||||
size_t _pos;
|
|
||||||
public:
|
|
||||||
CWriteDynamicBuffer(): _pos(0) {}
|
|
||||||
void Init()
|
|
||||||
{
|
|
||||||
_pos = 0;
|
_pos = 0;
|
||||||
}
|
}
|
||||||
void Write(const void *data, size_t size)
|
void WriteBytes(const void *data, size_t size)
|
||||||
{
|
{
|
||||||
if (_pos + size > _buffer.GetCapacity())
|
if (size > _size - _pos)
|
||||||
_buffer.EnsureCapacity(_pos + size);
|
throw 1;
|
||||||
memmove(((Byte *)_buffer) +_pos, data, size);
|
memcpy(_data + _pos, data, size);
|
||||||
_pos += size;
|
_pos += size;
|
||||||
}
|
}
|
||||||
operator Byte *() { return (Byte *)_buffer; };
|
void WriteByte(Byte b)
|
||||||
operator const Byte *() const { return (const Byte *)_buffer; };
|
{
|
||||||
size_t GetSize() const { return _pos; }
|
if (_size == _pos)
|
||||||
|
throw 1;
|
||||||
|
_data[_pos++] = b;
|
||||||
|
}
|
||||||
|
size_t GetPos() const { return _pos; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CHeaderOptions
|
struct CHeaderOptions
|
||||||
{
|
{
|
||||||
// bool UseAdditionalHeaderStreams;
|
|
||||||
bool CompressMainHeader;
|
bool CompressMainHeader;
|
||||||
bool WriteModified;
|
bool WriteCTime;
|
||||||
bool WriteCreated;
|
bool WriteATime;
|
||||||
bool WriteAccessed;
|
bool WriteMTime;
|
||||||
|
|
||||||
CHeaderOptions():
|
CHeaderOptions():
|
||||||
// UseAdditionalHeaderStreams(false),
|
|
||||||
CompressMainHeader(true),
|
CompressMainHeader(true),
|
||||||
WriteModified(true),
|
WriteCTime(false),
|
||||||
WriteCreated(false),
|
WriteATime(false),
|
||||||
WriteAccessed(false) {}
|
WriteMTime(true)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
class COutArchive
|
class COutArchive
|
||||||
@@ -80,56 +62,41 @@ class COutArchive
|
|||||||
UInt64 _prefixHeaderPos;
|
UInt64 _prefixHeaderPos;
|
||||||
|
|
||||||
HRESULT WriteDirect(const void *data, UInt32 size);
|
HRESULT WriteDirect(const void *data, UInt32 size);
|
||||||
HRESULT WriteDirectByte(Byte b) { return WriteDirect(&b, 1); }
|
|
||||||
HRESULT WriteDirectUInt32(UInt32 value);
|
|
||||||
HRESULT WriteDirectUInt64(UInt64 value);
|
|
||||||
|
|
||||||
HRESULT WriteBytes(const void *data, size_t size);
|
UInt64 GetPos() const;
|
||||||
HRESULT WriteBytes(const CByteBuffer &data);
|
void WriteBytes(const void *data, size_t size);
|
||||||
HRESULT WriteByte(Byte b);
|
void WriteBytes(const CByteBuffer &data) { WriteBytes(data, data.GetCapacity()); }
|
||||||
HRESULT WriteUInt32(UInt32 value);
|
void WriteByte(Byte b);
|
||||||
HRESULT WriteNumber(UInt64 value);
|
void WriteUInt32(UInt32 value);
|
||||||
HRESULT WriteID(UInt64 value) { return WriteNumber(value); }
|
void WriteUInt64(UInt64 value);
|
||||||
|
void WriteNumber(UInt64 value);
|
||||||
|
void WriteID(UInt64 value) { WriteNumber(value); }
|
||||||
|
|
||||||
HRESULT WriteFolder(const CFolder &folder);
|
void WriteFolder(const CFolder &folder);
|
||||||
HRESULT WriteFileHeader(const CFileItem &itemInfo);
|
HRESULT WriteFileHeader(const CFileItem &itemInfo);
|
||||||
HRESULT WriteBoolVector(const CBoolVector &boolVector);
|
void WriteBoolVector(const CBoolVector &boolVector);
|
||||||
HRESULT WriteHashDigests(
|
void WriteHashDigests(
|
||||||
const CRecordVector<bool> &digestsDefined,
|
const CRecordVector<bool> &digestsDefined,
|
||||||
const CRecordVector<UInt32> &hashDigests);
|
const CRecordVector<UInt32> &hashDigests);
|
||||||
|
|
||||||
HRESULT WritePackInfo(
|
void WritePackInfo(
|
||||||
UInt64 dataOffset,
|
UInt64 dataOffset,
|
||||||
const CRecordVector<UInt64> &packSizes,
|
const CRecordVector<UInt64> &packSizes,
|
||||||
const CRecordVector<bool> &packCRCsDefined,
|
const CRecordVector<bool> &packCRCsDefined,
|
||||||
const CRecordVector<UInt32> &packCRCs);
|
const CRecordVector<UInt32> &packCRCs);
|
||||||
|
|
||||||
HRESULT WriteUnPackInfo(const CObjectVector<CFolder> &folders);
|
void WriteUnpackInfo(const CObjectVector<CFolder> &folders);
|
||||||
|
|
||||||
HRESULT WriteSubStreamsInfo(
|
void WriteSubStreamsInfo(
|
||||||
const CObjectVector<CFolder> &folders,
|
const CObjectVector<CFolder> &folders,
|
||||||
const CRecordVector<CNum> &numUnPackStreamsInFolders,
|
const CRecordVector<CNum> &numUnpackStreamsInFolders,
|
||||||
const CRecordVector<UInt64> &unPackSizes,
|
const CRecordVector<UInt64> &unpackSizes,
|
||||||
const CRecordVector<bool> &digestsDefined,
|
const CRecordVector<bool> &digestsDefined,
|
||||||
const CRecordVector<UInt32> &hashDigests);
|
const CRecordVector<UInt32> &hashDigests);
|
||||||
|
|
||||||
/*
|
void SkipAlign(unsigned pos, unsigned alignSize);
|
||||||
HRESULT WriteStreamsInfo(
|
void WriteAlignedBoolHeader(const CBoolVector &v, int numDefined, Byte type, unsigned itemSize);
|
||||||
UInt64 dataOffset,
|
void WriteUInt64DefVector(const CUInt64DefVector &v, Byte type);
|
||||||
const CRecordVector<UInt64> &packSizes,
|
|
||||||
const CRecordVector<bool> &packCRCsDefined,
|
|
||||||
const CRecordVector<UInt32> &packCRCs,
|
|
||||||
bool externalFolders,
|
|
||||||
UInt64 externalFoldersStreamIndex,
|
|
||||||
const CObjectVector<CFolder> &folders,
|
|
||||||
const CRecordVector<CNum> &numUnPackStreamsInFolders,
|
|
||||||
const CRecordVector<UInt64> &unPackSizes,
|
|
||||||
const CRecordVector<bool> &digestsDefined,
|
|
||||||
const CRecordVector<UInt32> &hashDigests);
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
HRESULT WriteTime(const CObjectVector<CFileItem> &files, Byte type);
|
|
||||||
|
|
||||||
HRESULT EncodeStream(
|
HRESULT EncodeStream(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
@@ -137,23 +104,19 @@ class COutArchive
|
|||||||
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
|
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
|
||||||
HRESULT EncodeStream(
|
HRESULT EncodeStream(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
CEncoder &encoder, const CByteBuffer &data,
|
CEncoder &encoder, const CByteBuffer &data,
|
||||||
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
|
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
|
||||||
HRESULT WriteHeader(
|
void WriteHeader(
|
||||||
const CArchiveDatabase &database,
|
const CArchiveDatabase &db,
|
||||||
const CHeaderOptions &headerOptions,
|
const CHeaderOptions &headerOptions,
|
||||||
UInt64 &headerOffset);
|
UInt64 &headerOffset);
|
||||||
|
|
||||||
bool _mainMode;
|
|
||||||
|
|
||||||
bool _dynamicMode;
|
|
||||||
|
|
||||||
bool _countMode;
|
bool _countMode;
|
||||||
|
bool _writeToStream;
|
||||||
size_t _countSize;
|
size_t _countSize;
|
||||||
|
UInt32 _crc;
|
||||||
COutBuffer _outByte;
|
COutBuffer _outByte;
|
||||||
CWriteBufferLoc _outByte2;
|
CWriteBufferLoc _outByte2;
|
||||||
CWriteDynamicBuffer _dynamicBuffer;
|
|
||||||
UInt32 _crc;
|
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
bool _endMarker;
|
bool _endMarker;
|
||||||
@@ -177,8 +140,8 @@ public:
|
|||||||
HRESULT SkeepPrefixArchiveHeader();
|
HRESULT SkeepPrefixArchiveHeader();
|
||||||
HRESULT WriteDatabase(
|
HRESULT WriteDatabase(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
const CArchiveDatabase &database,
|
const CArchiveDatabase &db,
|
||||||
const CCompressionMethodMode *options,
|
const CCompressionMethodMode *options,
|
||||||
const CHeaderOptions &headerOptions);
|
const CHeaderOptions &headerOptions);
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ struct CPropMap
|
|||||||
STATPROPSTG StatPROPSTG;
|
STATPROPSTG StatPROPSTG;
|
||||||
};
|
};
|
||||||
|
|
||||||
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, kpidPackedSize, 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},
|
||||||
@@ -31,10 +31,10 @@ CPropMap kPropMap[] =
|
|||||||
{ 104, L"Pack4", kpidPackedSize4, VT_UI8},
|
{ 104, L"Pack4", kpidPackedSize4, VT_UI8},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{ NID::kCreationTime, NULL, kpidCreationTime, VT_FILETIME},
|
{ NID::kCTime, NULL, kpidCTime, VT_FILETIME},
|
||||||
{ NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME},
|
{ NID::kMTime, NULL, kpidMTime, VT_FILETIME},
|
||||||
{ NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME},
|
{ NID::kATime, NULL, kpidATime, VT_FILETIME},
|
||||||
{ NID::kWinAttributes, NULL, kpidAttributes, 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},
|
||||||
@@ -58,7 +58,7 @@ static int FindPropInMap(UInt64 filePropID)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CopyOneItem(CRecordVector<UInt64> &src,
|
static void CopyOneItem(CRecordVector<UInt64> &src,
|
||||||
CRecordVector<UInt64> &dest, UInt32 item)
|
CRecordVector<UInt64> &dest, UInt32 item)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < src.Size(); i++)
|
for (int i = 0; i < src.Size(); i++)
|
||||||
@@ -92,17 +92,17 @@ static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CHandler::FillPopIDs()
|
void CHandler::FillPopIDs()
|
||||||
{
|
{
|
||||||
_fileInfoPopIDs.Clear();
|
_fileInfoPopIDs.Clear();
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
#ifdef _7Z_VOL
|
||||||
if(_volumes.Size() < 1)
|
if(_volumes.Size() < 1)
|
||||||
return;
|
return;
|
||||||
const CVolume &volume = _volumes.Front();
|
const CVolume &volume = _volumes.Front();
|
||||||
const CArchiveDatabaseEx &_database = volume.Database;
|
const CArchiveDatabaseEx &_db = volume.Database;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CRecordVector<UInt64> fileInfoPopIDs = _database.ArchiveInfo.FileInfoPopIDs;
|
CRecordVector<UInt64> fileInfoPopIDs = _db.ArchiveInfo.FileInfoPopIDs;
|
||||||
|
|
||||||
RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
|
RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
|
||||||
RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
|
RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
|
||||||
@@ -111,13 +111,13 @@ void CHandler::FillPopIDs()
|
|||||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti);
|
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti);
|
||||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize);
|
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize);
|
||||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo);
|
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo);
|
||||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCreationTime);
|
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCTime);
|
||||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastWriteTime);
|
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kMTime);
|
||||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastAccessTime);
|
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kATime);
|
||||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
|
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
|
||||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
|
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
|
||||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
|
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
|
||||||
_fileInfoPopIDs += fileInfoPopIDs;
|
_fileInfoPopIDs += fileInfoPopIDs;
|
||||||
|
|
||||||
#ifndef _SFX
|
#ifndef _SFX
|
||||||
_fileInfoPopIDs.Add(97);
|
_fileInfoPopIDs.Add(97);
|
||||||
@@ -133,7 +133,7 @@ void CHandler::FillPopIDs()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _SFX
|
#ifndef _SFX
|
||||||
InsertToHead(_fileInfoPopIDs, NID::kLastWriteTime);
|
InsertToHead(_fileInfoPopIDs, NID::kMTime);
|
||||||
InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
|
InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
|
||||||
InsertToHead(_fileInfoPopIDs, NID::kSize);
|
InsertToHead(_fileInfoPopIDs, NID::kSize);
|
||||||
InsertToHead(_fileInfoPopIDs, NID::kName);
|
InsertToHead(_fileInfoPopIDs, NID::kName);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace N7z {
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kpidPackedSize0 = kpidUserDefined,
|
kpidPackedSize0 = kpidUserDefined,
|
||||||
kpidPackedSize1,
|
kpidPackedSize1,
|
||||||
kpidPackedSize2,
|
kpidPackedSize2,
|
||||||
kpidPackedSize3,
|
kpidPackedSize3,
|
||||||
kpidPackedSize4
|
kpidPackedSize4
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32
|
|||||||
_size += realProcessedSize;
|
_size += realProcessedSize;
|
||||||
if (processedSize != 0)
|
if (processedSize != 0)
|
||||||
*processedSize = realProcessedSize;
|
*processedSize = realProcessedSize;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(
|
STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "../../ICoder.h"
|
#include "../../ICoder.h"
|
||||||
#include "../../../Common/MyCom.h"
|
#include "../../../Common/MyCom.h"
|
||||||
|
|
||||||
class CSequentialInStreamSizeCount2:
|
class CSequentialInStreamSizeCount2:
|
||||||
public ISequentialInStream,
|
public ISequentialInStream,
|
||||||
public ICompressGetSubStreamSize,
|
public ICompressGetSubStreamSize,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
|
|||||||
+144
-354
@@ -22,7 +22,7 @@ static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;
|
|||||||
static const UInt32 kAlgorithmForBCJ2_LZMA = 1;
|
static const UInt32 kAlgorithmForBCJ2_LZMA = 1;
|
||||||
static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
|
static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
|
||||||
|
|
||||||
static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
|
static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
|
||||||
UInt64 position, UInt64 size, ICompressProgressInfo *progress)
|
UInt64 position, UInt64 size, ICompressProgressInfo *progress)
|
||||||
{
|
{
|
||||||
RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0));
|
RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0));
|
||||||
@@ -117,9 +117,9 @@ static int CompareFolderRefs(const int *p1, const int *p2, void *param)
|
|||||||
db.Folders[i1],
|
db.Folders[i1],
|
||||||
db.Folders[i2]));
|
db.Folders[i2]));
|
||||||
RINOZ(MyCompare(
|
RINOZ(MyCompare(
|
||||||
db.NumUnPackStreamsVector[i1],
|
db.NumUnpackStreamsVector[i1],
|
||||||
db.NumUnPackStreamsVector[i2]));
|
db.NumUnpackStreamsVector[i2]));
|
||||||
if (db.NumUnPackStreamsVector[i1] == 0)
|
if (db.NumUnpackStreamsVector[i1] == 0)
|
||||||
return 0;
|
return 0;
|
||||||
return CompareFiles(
|
return CompareFiles(
|
||||||
db.Files[db.FolderStartFileIndex[i1]],
|
db.Files[db.FolderStartFileIndex[i1]],
|
||||||
@@ -133,9 +133,9 @@ static int CompareEmptyItems(const int *p1, const int *p2, void *param)
|
|||||||
const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param;
|
const CObjectVector<CUpdateItem> &updateItems = *(const CObjectVector<CUpdateItem> *)param;
|
||||||
const CUpdateItem &u1 = updateItems[*p1];
|
const CUpdateItem &u1 = updateItems[*p1];
|
||||||
const CUpdateItem &u2 = updateItems[*p2];
|
const CUpdateItem &u2 = updateItems[*p2];
|
||||||
if (u1.IsDirectory != u2.IsDirectory)
|
if (u1.IsDir != u2.IsDir)
|
||||||
return (u1.IsDirectory) ? 1 : -1;
|
return (u1.IsDir) ? 1 : -1;
|
||||||
if (u1.IsDirectory)
|
if (u1.IsDir)
|
||||||
{
|
{
|
||||||
if (u1.IsAnti != u2.IsAnti)
|
if (u1.IsAnti != u2.IsAnti)
|
||||||
return (u1.IsAnti ? 1 : -1);
|
return (u1.IsAnti ? 1 : -1);
|
||||||
@@ -147,8 +147,8 @@ static int CompareEmptyItems(const int *p1, const int *p2, void *param)
|
|||||||
return MyStringCompareNoCase(u1.Name, u2.Name);
|
return MyStringCompareNoCase(u1.Name, u2.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *g_Exts =
|
static const char *g_Exts =
|
||||||
" lzma 7z ace arc arj bz bz2 deb lzo lzx gz pak rpm sit tgz tbz tbz2 tgz cab ha lha lzh rar zoo"
|
" lzma 7z ace arc arj bz bz2 deb lzo lzx gz pak rpm sit tgz tbz tbz2 tgz cab ha lha lzh rar zoo"
|
||||||
" zip jar ear war msi"
|
" zip jar ear war msi"
|
||||||
" 3gp avi mov mpeg mpg mpe wmv"
|
" 3gp avi mov mpeg mpg mpe wmv"
|
||||||
" aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav"
|
" aac ape fla flac la mp3 m4a mp4 ofr ogg pac ra rm rka shn swa tta wv wma wav"
|
||||||
@@ -161,7 +161,7 @@ static const char *g_Exts =
|
|||||||
" iso bin nrg mdf img pdi tar cpio xpi"
|
" iso bin nrg mdf img pdi tar cpio xpi"
|
||||||
" vfd vhd vud vmc vsv"
|
" vfd vhd vud vmc vsv"
|
||||||
" vmdk dsk nvram vmem vmsd vmsn vmss vmtm"
|
" vmdk dsk nvram vmem vmsd vmsn vmss vmtm"
|
||||||
" inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def"
|
" inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def"
|
||||||
" f77 f f90 f95"
|
" f77 f f90 f95"
|
||||||
" asm sql manifest dep "
|
" asm sql manifest dep "
|
||||||
" mak clw csproj vcproj sln dsp dsw "
|
" mak clw csproj vcproj sln dsp dsw "
|
||||||
@@ -212,29 +212,29 @@ int GetExtIndex(const char *ext)
|
|||||||
|
|
||||||
struct CRefItem
|
struct CRefItem
|
||||||
{
|
{
|
||||||
UInt32 Index;
|
|
||||||
const CUpdateItem *UpdateItem;
|
const CUpdateItem *UpdateItem;
|
||||||
|
UInt32 Index;
|
||||||
UInt32 ExtensionPos;
|
UInt32 ExtensionPos;
|
||||||
UInt32 NamePos;
|
UInt32 NamePos;
|
||||||
int ExtensionIndex;
|
int ExtensionIndex;
|
||||||
CRefItem(UInt32 index, const CUpdateItem &updateItem, bool sortByType):
|
CRefItem(UInt32 index, const CUpdateItem &ui, bool sortByType):
|
||||||
|
UpdateItem(&ui),
|
||||||
Index(index),
|
Index(index),
|
||||||
UpdateItem(&updateItem),
|
|
||||||
ExtensionPos(0),
|
ExtensionPos(0),
|
||||||
NamePos(0),
|
NamePos(0),
|
||||||
ExtensionIndex(0)
|
ExtensionIndex(0)
|
||||||
{
|
{
|
||||||
if (sortByType)
|
if (sortByType)
|
||||||
{
|
{
|
||||||
int slashPos = GetReverseSlashPos(updateItem.Name);
|
int slashPos = GetReverseSlashPos(ui.Name);
|
||||||
NamePos = ((slashPos >= 0) ? (slashPos + 1) : 0);
|
NamePos = ((slashPos >= 0) ? (slashPos + 1) : 0);
|
||||||
int dotPos = updateItem.Name.ReverseFind(L'.');
|
int dotPos = ui.Name.ReverseFind(L'.');
|
||||||
if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
|
if (dotPos < 0 || (dotPos < slashPos && slashPos >= 0))
|
||||||
ExtensionPos = updateItem.Name.Length();
|
ExtensionPos = ui.Name.Length();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ExtensionPos = dotPos + 1;
|
ExtensionPos = dotPos + 1;
|
||||||
UString us = updateItem.Name.Mid(ExtensionPos);
|
UString us = ui.Name.Mid(ExtensionPos);
|
||||||
if (!us.IsEmpty())
|
if (!us.IsEmpty())
|
||||||
{
|
{
|
||||||
us.MakeLower();
|
us.MakeLower();
|
||||||
@@ -264,9 +264,9 @@ static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *para
|
|||||||
const CUpdateItem &u1 = *a1.UpdateItem;
|
const CUpdateItem &u1 = *a1.UpdateItem;
|
||||||
const CUpdateItem &u2 = *a2.UpdateItem;
|
const CUpdateItem &u2 = *a2.UpdateItem;
|
||||||
int n;
|
int n;
|
||||||
if (u1.IsDirectory != u2.IsDirectory)
|
if (u1.IsDir != u2.IsDir)
|
||||||
return (u1.IsDirectory) ? 1 : -1;
|
return (u1.IsDir) ? 1 : -1;
|
||||||
if (u1.IsDirectory)
|
if (u1.IsDir)
|
||||||
{
|
{
|
||||||
if (u1.IsAnti != u2.IsAnti)
|
if (u1.IsAnti != u2.IsAnti)
|
||||||
return (u1.IsAnti ? 1 : -1);
|
return (u1.IsAnti ? 1 : -1);
|
||||||
@@ -279,8 +279,9 @@ static int CompareUpdateItems(const CRefItem *p1, const CRefItem *p2, void *para
|
|||||||
RINOZ(MyCompare(a1.ExtensionIndex, a2.ExtensionIndex))
|
RINOZ(MyCompare(a1.ExtensionIndex, a2.ExtensionIndex))
|
||||||
RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));
|
RINOZ(MyStringCompareNoCase(u1.Name + a1.ExtensionPos, u2.Name + a2.ExtensionPos));
|
||||||
RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));
|
RINOZ(MyStringCompareNoCase(u1.Name + a1.NamePos, u2.Name + a2.NamePos));
|
||||||
if (u1.IsLastWriteTimeDefined && u2.IsLastWriteTimeDefined)
|
if (!u1.MTimeDefined && u2.MTimeDefined) return 1;
|
||||||
RINOZ(CompareFileTime(&u1.LastWriteTime, &u2.LastWriteTime));
|
if (u1.MTimeDefined && !u2.MTimeDefined) return -1;
|
||||||
|
if (u1.MTimeDefined && u2.MTimeDefined) RINOZ(MyCompare(u1.MTime, u2.MTime));
|
||||||
RINOZ(MyCompare(u1.Size, u2.Size))
|
RINOZ(MyCompare(u1.Size, u2.Size))
|
||||||
}
|
}
|
||||||
return MyStringCompareNoCase(u1.Name, u2.Name);
|
return MyStringCompareNoCase(u1.Name, u2.Name);
|
||||||
@@ -313,7 +314,7 @@ static const UInt64 k_LZMA = 0x030101;
|
|||||||
static const UInt64 k_BCJ = 0x03030103;
|
static const UInt64 k_BCJ = 0x03030103;
|
||||||
static const UInt64 k_BCJ2 = 0x0303011B;
|
static const UInt64 k_BCJ2 = 0x0303011B;
|
||||||
|
|
||||||
static bool GetMethodFull(UInt64 methodID,
|
static bool GetMethodFull(UInt64 methodID,
|
||||||
UInt32 numInStreams, CMethodFull &methodResult)
|
UInt32 numInStreams, CMethodFull &methodResult)
|
||||||
{
|
{
|
||||||
methodResult.Id = methodID;
|
methodResult.Id = methodID;
|
||||||
@@ -322,7 +323,7 @@ static bool GetMethodFull(UInt64 methodID,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool MakeExeMethod(const CCompressionMethodMode &method,
|
static bool MakeExeMethod(const CCompressionMethodMode &method,
|
||||||
bool bcj2Filter, CCompressionMethodMode &exeMethod)
|
bool bcj2Filter, CCompressionMethodMode &exeMethod)
|
||||||
{
|
{
|
||||||
exeMethod = method;
|
exeMethod = method;
|
||||||
@@ -392,10 +393,10 @@ static bool MakeExeMethod(const CCompressionMethodMode &method,
|
|||||||
exeMethod.Binds.Add(bind);
|
exeMethod.Binds.Add(bind);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SplitFilesToGroups(
|
static void SplitFilesToGroups(
|
||||||
const CCompressionMethodMode &method,
|
const CCompressionMethodMode &method,
|
||||||
bool useFilters, bool maxFilter,
|
bool useFilters, bool maxFilter,
|
||||||
const CObjectVector<CUpdateItem> &updateItems,
|
const CObjectVector<CUpdateItem> &updateItems,
|
||||||
CObjectVector<CSolidGroup> &groups)
|
CObjectVector<CSolidGroup> &groups)
|
||||||
@@ -411,14 +412,14 @@ static void SplitFilesToGroups(
|
|||||||
int i;
|
int i;
|
||||||
for (i = 0; i < updateItems.Size(); i++)
|
for (i = 0; i < updateItems.Size(); i++)
|
||||||
{
|
{
|
||||||
const CUpdateItem &updateItem = updateItems[i];
|
const CUpdateItem &ui = updateItems[i];
|
||||||
if (!updateItem.NewData)
|
if (!ui.NewData)
|
||||||
continue;
|
continue;
|
||||||
if (!updateItem.HasStream())
|
if (!ui.HasStream())
|
||||||
continue;
|
continue;
|
||||||
if (useFilters)
|
if (useFilters)
|
||||||
{
|
{
|
||||||
const UString name = updateItem.Name;
|
const UString name = ui.Name;
|
||||||
int dotPos = name.ReverseFind(L'.');
|
int dotPos = name.ReverseFind(L'.');
|
||||||
if (dotPos >= 0)
|
if (dotPos >= 0)
|
||||||
{
|
{
|
||||||
@@ -442,31 +443,31 @@ static void SplitFilesToGroups(
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FromUpdateItemToFileItem(const CUpdateItem &updateItem,
|
static void FromUpdateItemToFileItem(const CUpdateItem &ui,
|
||||||
CFileItem &file)
|
CFileItem &file, CFileItem2 &file2)
|
||||||
{
|
{
|
||||||
file.Name = NItemName::MakeLegalName(updateItem.Name);
|
file.Name = NItemName::MakeLegalName(ui.Name);
|
||||||
if (updateItem.AttributesAreDefined)
|
if (ui.AttribDefined)
|
||||||
file.SetAttributes(updateItem.Attributes);
|
file.SetAttrib(ui.Attrib);
|
||||||
|
|
||||||
if (updateItem.IsCreationTimeDefined)
|
file2.CTime = ui.CTime; file2.CTimeDefined = ui.CTimeDefined;
|
||||||
file.SetCreationTime(updateItem.CreationTime);
|
file2.ATime = ui.ATime; file2.ATimeDefined = ui.ATimeDefined;
|
||||||
if (updateItem.IsLastWriteTimeDefined)
|
file2.MTime = ui.MTime; file2.MTimeDefined = ui.MTimeDefined;
|
||||||
file.SetLastWriteTime(updateItem.LastWriteTime);
|
file2.IsAnti = ui.IsAnti;
|
||||||
if (updateItem.IsLastAccessTimeDefined)
|
file2.StartPosDefined = false;
|
||||||
file.SetLastAccessTime(updateItem.LastAccessTime);
|
|
||||||
|
file.Size = ui.Size;
|
||||||
file.UnPackSize = updateItem.Size;
|
file.IsDir = ui.IsDir;
|
||||||
file.IsDirectory = updateItem.IsDirectory;
|
file.HasStream = ui.HasStream();
|
||||||
file.IsAnti = updateItem.IsAnti;
|
|
||||||
file.HasStream = updateItem.HasStream();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT Update2(
|
static HRESULT Update2(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
IInStream *inStream,
|
IInStream *inStream,
|
||||||
const CArchiveDatabaseEx *database,
|
const CArchiveDatabaseEx *db,
|
||||||
const CObjectVector<CUpdateItem> &updateItems,
|
const CObjectVector<CUpdateItem> &updateItems,
|
||||||
|
COutArchive &archive,
|
||||||
|
CArchiveDatabase &newDatabase,
|
||||||
ISequentialOutStream *seqOutStream,
|
ISequentialOutStream *seqOutStream,
|
||||||
IArchiveUpdateCallback *updateCallback,
|
IArchiveUpdateCallback *updateCallback,
|
||||||
const CUpdateOptions &options)
|
const CUpdateOptions &options)
|
||||||
@@ -481,17 +482,17 @@ static HRESULT Update2(
|
|||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
UInt64 startBlockSize = database != 0 ? database->ArchiveInfo.StartPosition: 0;
|
UInt64 startBlockSize = db != 0 ? db->ArchiveInfo.StartPosition: 0;
|
||||||
if (startBlockSize > 0 && !options.RemoveSfxBlock)
|
if (startBlockSize > 0 && !options.RemoveSfxBlock)
|
||||||
{
|
{
|
||||||
RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
|
RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
CRecordVector<int> fileIndexToUpdateIndexMap;
|
CRecordVector<int> fileIndexToUpdateIndexMap;
|
||||||
if (database != 0)
|
if (db != 0)
|
||||||
{
|
{
|
||||||
fileIndexToUpdateIndexMap.Reserve(database->Files.Size());
|
fileIndexToUpdateIndexMap.Reserve(db->Files.Size());
|
||||||
for (int i = 0; i < database->Files.Size(); i++)
|
for (int i = 0; i < db->Files.Size(); i++)
|
||||||
fileIndexToUpdateIndexMap.Add(-1);
|
fileIndexToUpdateIndexMap.Add(-1);
|
||||||
}
|
}
|
||||||
int i;
|
int i;
|
||||||
@@ -503,17 +504,17 @@ static HRESULT Update2(
|
|||||||
}
|
}
|
||||||
|
|
||||||
CRecordVector<int> folderRefs;
|
CRecordVector<int> folderRefs;
|
||||||
if (database != 0)
|
if (db != 0)
|
||||||
{
|
{
|
||||||
for(i = 0; i < database->Folders.Size(); i++)
|
for(i = 0; i < db->Folders.Size(); i++)
|
||||||
{
|
{
|
||||||
CNum indexInFolder = 0;
|
CNum indexInFolder = 0;
|
||||||
CNum numCopyItems = 0;
|
CNum numCopyItems = 0;
|
||||||
CNum numUnPackStreams = database->NumUnPackStreamsVector[i];
|
CNum numUnpackStreams = db->NumUnpackStreamsVector[i];
|
||||||
for (CNum fileIndex = database->FolderStartFileIndex[i];
|
for (CNum fileIndex = db->FolderStartFileIndex[i];
|
||||||
indexInFolder < numUnPackStreams; fileIndex++)
|
indexInFolder < numUnpackStreams; fileIndex++)
|
||||||
{
|
{
|
||||||
if (database->Files[fileIndex].HasStream)
|
if (db->Files[fileIndex].HasStream)
|
||||||
{
|
{
|
||||||
indexInFolder++;
|
indexInFolder++;
|
||||||
int updateIndex = fileIndexToUpdateIndexMap[fileIndex];
|
int updateIndex = fileIndexToUpdateIndexMap[fileIndex];
|
||||||
@@ -522,38 +523,35 @@ static HRESULT Update2(
|
|||||||
numCopyItems++;
|
numCopyItems++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (numCopyItems != numUnPackStreams && numCopyItems != 0)
|
if (numCopyItems != numUnpackStreams && numCopyItems != 0)
|
||||||
return E_NOTIMPL; // It needs repacking !!!
|
return E_NOTIMPL; // It needs repacking !!!
|
||||||
if (numCopyItems > 0)
|
if (numCopyItems > 0)
|
||||||
folderRefs.Add(i);
|
folderRefs.Add(i);
|
||||||
}
|
}
|
||||||
folderRefs.Sort(CompareFolderRefs, (void *)database);
|
folderRefs.Sort(CompareFolderRefs, (void *)db);
|
||||||
}
|
}
|
||||||
|
|
||||||
CArchiveDatabase newDatabase;
|
|
||||||
|
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
|
|
||||||
COutArchive archive;
|
|
||||||
RINOK(archive.Create(seqOutStream, false));
|
RINOK(archive.Create(seqOutStream, false));
|
||||||
RINOK(archive.SkeepPrefixArchiveHeader());
|
RINOK(archive.SkeepPrefixArchiveHeader());
|
||||||
UInt64 complexity = 0;
|
UInt64 complexity = 0;
|
||||||
for(i = 0; i < folderRefs.Size(); i++)
|
for(i = 0; i < folderRefs.Size(); i++)
|
||||||
complexity += database->GetFolderFullPackSize(folderRefs[i]);
|
complexity += db->GetFolderFullPackSize(folderRefs[i]);
|
||||||
UInt64 inSizeForReduce = 0;
|
UInt64 inSizeForReduce = 0;
|
||||||
for(i = 0; i < updateItems.Size(); i++)
|
for(i = 0; i < updateItems.Size(); i++)
|
||||||
{
|
{
|
||||||
const CUpdateItem &updateItem = updateItems[i];
|
const CUpdateItem &ui = updateItems[i];
|
||||||
if (updateItem.NewData)
|
if (ui.NewData)
|
||||||
{
|
{
|
||||||
complexity += updateItem.Size;
|
complexity += ui.Size;
|
||||||
if (numSolidFiles == 1)
|
if (numSolidFiles == 1)
|
||||||
{
|
{
|
||||||
if (updateItem.Size > inSizeForReduce)
|
if (ui.Size > inSizeForReduce)
|
||||||
inSizeForReduce = updateItem.Size;
|
inSizeForReduce = ui.Size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
inSizeForReduce += updateItem.Size;
|
inSizeForReduce += ui.Size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RINOK(updateCallback->SetTotal(complexity));
|
RINOK(updateCallback->SetTotal(complexity));
|
||||||
@@ -573,57 +571,62 @@ static HRESULT Update2(
|
|||||||
int folderIndex = folderRefs[i];
|
int folderIndex = folderRefs[i];
|
||||||
|
|
||||||
lps->ProgressOffset = complexity;
|
lps->ProgressOffset = complexity;
|
||||||
UInt64 packSize = database->GetFolderFullPackSize(folderIndex);
|
UInt64 packSize = db->GetFolderFullPackSize(folderIndex);
|
||||||
RINOK(WriteRange(inStream, archive.SeqStream,
|
RINOK(WriteRange(inStream, archive.SeqStream,
|
||||||
database->GetFolderStreamPos(folderIndex, 0), packSize, progress));
|
db->GetFolderStreamPos(folderIndex, 0), packSize, progress));
|
||||||
complexity += packSize;
|
complexity += packSize;
|
||||||
|
|
||||||
const CFolder &folder = database->Folders[folderIndex];
|
const CFolder &folder = db->Folders[folderIndex];
|
||||||
CNum startIndex = database->FolderStartPackStreamIndex[folderIndex];
|
CNum startIndex = db->FolderStartPackStreamIndex[folderIndex];
|
||||||
for (int j = 0; j < folder.PackStreams.Size(); j++)
|
for (int j = 0; j < folder.PackStreams.Size(); j++)
|
||||||
{
|
{
|
||||||
newDatabase.PackSizes.Add(database->PackSizes[startIndex + j]);
|
newDatabase.PackSizes.Add(db->PackSizes[startIndex + j]);
|
||||||
// newDatabase.PackCRCsDefined.Add(database.PackCRCsDefined[startIndex + j]);
|
// newDatabase.PackCRCsDefined.Add(db.PackCRCsDefined[startIndex + j]);
|
||||||
// newDatabase.PackCRCs.Add(database.PackCRCs[startIndex + j]);
|
// newDatabase.PackCRCs.Add(db.PackCRCs[startIndex + j]);
|
||||||
}
|
}
|
||||||
newDatabase.Folders.Add(folder);
|
newDatabase.Folders.Add(folder);
|
||||||
|
|
||||||
CNum numUnPackStreams = database->NumUnPackStreamsVector[folderIndex];
|
CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];
|
||||||
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
|
newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams);
|
||||||
|
|
||||||
CNum indexInFolder = 0;
|
CNum indexInFolder = 0;
|
||||||
for (CNum fi = database->FolderStartFileIndex[folderIndex];
|
for (CNum fi = db->FolderStartFileIndex[folderIndex];
|
||||||
indexInFolder < numUnPackStreams; fi++)
|
indexInFolder < numUnpackStreams; fi++)
|
||||||
{
|
{
|
||||||
CFileItem file = database->Files[fi];
|
CFileItem file;
|
||||||
|
CFileItem2 file2;
|
||||||
|
db->GetFile(fi, file, file2);
|
||||||
if (file.HasStream)
|
if (file.HasStream)
|
||||||
{
|
{
|
||||||
indexInFolder++;
|
indexInFolder++;
|
||||||
int updateIndex = fileIndexToUpdateIndexMap[fi];
|
int updateIndex = fileIndexToUpdateIndexMap[fi];
|
||||||
if (updateIndex >= 0)
|
if (updateIndex >= 0)
|
||||||
{
|
{
|
||||||
const CUpdateItem &updateItem = updateItems[updateIndex];
|
const CUpdateItem &ui = updateItems[updateIndex];
|
||||||
if (updateItem.NewProperties)
|
if (ui.NewProperties)
|
||||||
{
|
{
|
||||||
CFileItem file2;
|
CFileItem uf;
|
||||||
FromUpdateItemToFileItem(updateItem, file2);
|
FromUpdateItemToFileItem(ui, uf, file2);
|
||||||
file2.UnPackSize = file.UnPackSize;
|
uf.Size = file.Size;
|
||||||
file2.FileCRC = file.FileCRC;
|
uf.Crc = file.Crc;
|
||||||
file2.IsFileCRCDefined = file.IsFileCRCDefined;
|
uf.CrcDefined = file.CrcDefined;
|
||||||
file2.HasStream = file.HasStream;
|
uf.HasStream = file.HasStream;
|
||||||
file = file2;
|
file = uf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
newDatabase.Files.Add(file);
|
newDatabase.AddFile(file, file2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
folderRefs.ClearAndFree();
|
||||||
|
fileIndexToUpdateIndexMap.ClearAndFree();
|
||||||
|
|
||||||
/////////////////////////////////////////
|
/////////////////////////////////////////
|
||||||
// Compress New Files
|
// Compress New Files
|
||||||
|
|
||||||
CObjectVector<CSolidGroup> groups;
|
CObjectVector<CSolidGroup> groups;
|
||||||
SplitFilesToGroups(*options.Method, options.UseFilters, options.MaxFilter,
|
SplitFilesToGroups(*options.Method, options.UseFilters, options.MaxFilter,
|
||||||
updateItems, groups);
|
updateItems, groups);
|
||||||
|
|
||||||
const UInt32 kMinReduceSize = (1 << 16);
|
const UInt32 kMinReduceSize = (1 << 16);
|
||||||
@@ -651,13 +654,13 @@ static HRESULT Update2(
|
|||||||
UInt32 index = refItems[i].Index;
|
UInt32 index = refItems[i].Index;
|
||||||
indices.Add(index);
|
indices.Add(index);
|
||||||
/*
|
/*
|
||||||
const CUpdateItem &updateItem = updateItems[index];
|
const CUpdateItem &ui = updateItems[index];
|
||||||
CFileItem file;
|
CFileItem file;
|
||||||
if (updateItem.NewProperties)
|
if (ui.NewProperties)
|
||||||
FromUpdateItemToFileItem(updateItem, file);
|
FromUpdateItemToFileItem(ui, file);
|
||||||
else
|
else
|
||||||
file = database.Files[updateItem.IndexInArchive];
|
file = db.Files[ui.IndexInArchive];
|
||||||
if (file.IsAnti || file.IsDirectory)
|
if (file.IsAnti || file.IsDir)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
newDatabase.Files.Add(file);
|
newDatabase.Files.Add(file);
|
||||||
*/
|
*/
|
||||||
@@ -670,16 +673,16 @@ static HRESULT Update2(
|
|||||||
UInt64 totalSize = 0;
|
UInt64 totalSize = 0;
|
||||||
int numSubFiles;
|
int numSubFiles;
|
||||||
UString prevExtension;
|
UString prevExtension;
|
||||||
for (numSubFiles = 0; i + numSubFiles < numFiles &&
|
for (numSubFiles = 0; i + numSubFiles < numFiles &&
|
||||||
numSubFiles < numSolidFiles; numSubFiles++)
|
numSubFiles < numSolidFiles; numSubFiles++)
|
||||||
{
|
{
|
||||||
const CUpdateItem &updateItem = updateItems[indices[i + numSubFiles]];
|
const CUpdateItem &ui = updateItems[indices[i + numSubFiles]];
|
||||||
totalSize += updateItem.Size;
|
totalSize += ui.Size;
|
||||||
if (totalSize > options.NumSolidBytes)
|
if (totalSize > options.NumSolidBytes)
|
||||||
break;
|
break;
|
||||||
if (options.SolidExtension)
|
if (options.SolidExtension)
|
||||||
{
|
{
|
||||||
UString ext = updateItem.GetExtension();
|
UString ext = ui.GetExtension();
|
||||||
if (numSubFiles == 0)
|
if (numSubFiles == 0)
|
||||||
prevExtension = ext;
|
prevExtension = ext;
|
||||||
else
|
else
|
||||||
@@ -699,29 +702,30 @@ static HRESULT Update2(
|
|||||||
int startPackIndex = newDatabase.PackSizes.Size();
|
int startPackIndex = newDatabase.PackSizes.Size();
|
||||||
RINOK(encoder.Encode(
|
RINOK(encoder.Encode(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
solidInStream, NULL, &inSizeForReduce, folderItem,
|
solidInStream, NULL, &inSizeForReduce, folderItem,
|
||||||
archive.SeqStream, newDatabase.PackSizes, progress));
|
archive.SeqStream, newDatabase.PackSizes, progress));
|
||||||
|
|
||||||
for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)
|
for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)
|
||||||
lps->OutSize += newDatabase.PackSizes[startPackIndex];
|
lps->OutSize += newDatabase.PackSizes[startPackIndex];
|
||||||
|
|
||||||
lps->InSize += folderItem.GetUnPackSize();
|
lps->InSize += folderItem.GetUnpackSize();
|
||||||
// for()
|
// for()
|
||||||
// newDatabase.PackCRCsDefined.Add(false);
|
// newDatabase.PackCRCsDefined.Add(false);
|
||||||
// newDatabase.PackCRCs.Add(0);
|
// newDatabase.PackCRCs.Add(0);
|
||||||
|
|
||||||
newDatabase.Folders.Add(folderItem);
|
newDatabase.Folders.Add(folderItem);
|
||||||
|
|
||||||
CNum numUnPackStreams = 0;
|
CNum numUnpackStreams = 0;
|
||||||
for (int subIndex = 0; subIndex < numSubFiles; subIndex++)
|
for (int subIndex = 0; subIndex < numSubFiles; subIndex++)
|
||||||
{
|
{
|
||||||
const CUpdateItem &updateItem = updateItems[indices[i + subIndex]];
|
const CUpdateItem &ui = updateItems[indices[i + subIndex]];
|
||||||
CFileItem file;
|
CFileItem file;
|
||||||
if (updateItem.NewProperties)
|
CFileItem2 file2;
|
||||||
FromUpdateItemToFileItem(updateItem, file);
|
if (ui.NewProperties)
|
||||||
|
FromUpdateItemToFileItem(ui, file, file2);
|
||||||
else
|
else
|
||||||
file = database->Files[updateItem.IndexInArchive];
|
db->GetFile(ui.IndexInArchive, file, file2);
|
||||||
if (file.IsAnti || file.IsDirectory)
|
if (file2.IsAnti || file.IsDir)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -734,28 +738,30 @@ static HRESULT Update2(
|
|||||||
// file.Name += L".locked";
|
// file.Name += L".locked";
|
||||||
}
|
}
|
||||||
|
|
||||||
file.FileCRC = inStreamSpec->CRCs[subIndex];
|
file.Crc = inStreamSpec->CRCs[subIndex];
|
||||||
file.UnPackSize = inStreamSpec->Sizes[subIndex];
|
file.Size = inStreamSpec->Sizes[subIndex];
|
||||||
if (file.UnPackSize != 0)
|
if (file.Size != 0)
|
||||||
{
|
{
|
||||||
file.IsFileCRCDefined = true;
|
file.CrcDefined = true;
|
||||||
file.HasStream = true;
|
file.HasStream = true;
|
||||||
numUnPackStreams++;
|
numUnpackStreams++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
file.IsFileCRCDefined = false;
|
file.CrcDefined = false;
|
||||||
file.HasStream = false;
|
file.HasStream = false;
|
||||||
}
|
}
|
||||||
newDatabase.Files.Add(file);
|
newDatabase.AddFile(file, file2);
|
||||||
}
|
}
|
||||||
// numUnPackStreams = 0 is very bad case for locked files
|
// numUnpackStreams = 0 is very bad case for locked files
|
||||||
// v3.13 doesn't understand it.
|
// v3.13 doesn't understand it.
|
||||||
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
|
newDatabase.NumUnpackStreamsVector.Add(numUnpackStreams);
|
||||||
i += numSubFiles;
|
i += numSubFiles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
groups.ClearAndFree();
|
||||||
|
|
||||||
{
|
{
|
||||||
/////////////////////////////////////////
|
/////////////////////////////////////////
|
||||||
// Write Empty Files & Folders
|
// Write Empty Files & Folders
|
||||||
@@ -763,267 +769,51 @@ static HRESULT Update2(
|
|||||||
CRecordVector<int> emptyRefs;
|
CRecordVector<int> emptyRefs;
|
||||||
for(i = 0; i < updateItems.Size(); i++)
|
for(i = 0; i < updateItems.Size(); i++)
|
||||||
{
|
{
|
||||||
const CUpdateItem &updateItem = updateItems[i];
|
const CUpdateItem &ui = updateItems[i];
|
||||||
if (updateItem.NewData)
|
if (ui.NewData)
|
||||||
{
|
{
|
||||||
if (updateItem.HasStream())
|
if (ui.HasStream())
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (updateItem.IndexInArchive != -1)
|
if (ui.IndexInArchive != -1)
|
||||||
if (database->Files[updateItem.IndexInArchive].HasStream)
|
if (db->Files[ui.IndexInArchive].HasStream)
|
||||||
continue;
|
continue;
|
||||||
emptyRefs.Add(i);
|
emptyRefs.Add(i);
|
||||||
}
|
}
|
||||||
emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
|
emptyRefs.Sort(CompareEmptyItems, (void *)&updateItems);
|
||||||
for(i = 0; i < emptyRefs.Size(); i++)
|
for (i = 0; i < emptyRefs.Size(); i++)
|
||||||
{
|
{
|
||||||
const CUpdateItem &updateItem = updateItems[emptyRefs[i]];
|
const CUpdateItem &ui = updateItems[emptyRefs[i]];
|
||||||
CFileItem file;
|
CFileItem file;
|
||||||
if (updateItem.NewProperties)
|
CFileItem2 file2;
|
||||||
FromUpdateItemToFileItem(updateItem, file);
|
if (ui.NewProperties)
|
||||||
|
FromUpdateItemToFileItem(ui, file, file2);
|
||||||
else
|
else
|
||||||
file = database->Files[updateItem.IndexInArchive];
|
db->GetFile(ui.IndexInArchive, file, file2);
|
||||||
newDatabase.Files.Add(file);
|
newDatabase.AddFile(file, file2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
newDatabase.ReserveDown();
|
||||||
if (newDatabase.Files.Size() != updateItems.Size())
|
|
||||||
return E_FAIL;
|
|
||||||
*/
|
|
||||||
|
|
||||||
return archive.WriteDatabase(EXTERNAL_CODECS_LOC_VARS
|
|
||||||
newDatabase, options.HeaderMethod, options.HeaderOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
|
|
||||||
static const UInt64 k_Copy = 0x0;
|
|
||||||
|
|
||||||
static HRESULT WriteVolumeHeader(COutArchive &archive, CFileItem &file, const CUpdateOptions &options)
|
|
||||||
{
|
|
||||||
CCoderInfo coder;
|
|
||||||
coder.NumInStreams = coder.NumOutStreams = 1;
|
|
||||||
coder.MethodID = k_Copy;
|
|
||||||
|
|
||||||
CFolder folder;
|
|
||||||
folder.Coders.Add(coder);
|
|
||||||
folder.PackStreams.Add(0);
|
|
||||||
|
|
||||||
CNum numUnPackStreams = 0;
|
|
||||||
if (file.UnPackSize != 0)
|
|
||||||
{
|
|
||||||
file.IsFileCRCDefined = true;
|
|
||||||
file.HasStream = true;
|
|
||||||
numUnPackStreams++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw 1;
|
|
||||||
file.IsFileCRCDefined = false;
|
|
||||||
file.HasStream = false;
|
|
||||||
}
|
|
||||||
folder.UnPackSizes.Add(file.UnPackSize);
|
|
||||||
|
|
||||||
CArchiveDatabase newDatabase;
|
|
||||||
newDatabase.Files.Add(file);
|
|
||||||
newDatabase.Folders.Add(folder);
|
|
||||||
newDatabase.NumUnPackStreamsVector.Add(numUnPackStreams);
|
|
||||||
newDatabase.PackSizes.Add(file.UnPackSize);
|
|
||||||
newDatabase.PackCRCsDefined.Add(false);
|
|
||||||
newDatabase.PackCRCs.Add(file.FileCRC);
|
|
||||||
|
|
||||||
return archive.WriteDatabase(newDatabase,
|
|
||||||
options.HeaderMethod,
|
|
||||||
false,
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT UpdateVolume(
|
|
||||||
IInStream *inStream,
|
|
||||||
const CArchiveDatabaseEx *database,
|
|
||||||
CObjectVector<CUpdateItem> &updateItems,
|
|
||||||
ISequentialOutStream *seqOutStream,
|
|
||||||
IArchiveUpdateCallback *updateCallback,
|
|
||||||
const CUpdateOptions &options)
|
|
||||||
{
|
|
||||||
if (updateItems.Size() != 1)
|
|
||||||
return E_NOTIMPL;
|
|
||||||
|
|
||||||
CMyComPtr<IArchiveUpdateCallback2> volumeCallback;
|
|
||||||
RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback));
|
|
||||||
if (!volumeCallback)
|
|
||||||
return E_NOTIMPL;
|
|
||||||
|
|
||||||
CMyComPtr<ISequentialInStream> fileStream;
|
|
||||||
HRESULT result = updateCallback->GetStream(0, &fileStream);
|
|
||||||
if (result != S_OK && result != S_FALSE)
|
|
||||||
return result;
|
|
||||||
if (result == S_FALSE)
|
|
||||||
return E_FAIL;
|
|
||||||
|
|
||||||
CFileItem file;
|
|
||||||
|
|
||||||
const CUpdateItem &updateItem = updateItems[0];
|
|
||||||
if (updateItem.NewProperties)
|
|
||||||
FromUpdateItemToFileItem(updateItem, file);
|
|
||||||
else
|
|
||||||
file = database->Files[updateItem.IndexInArchive];
|
|
||||||
if (file.IsAnti || file.IsDirectory)
|
|
||||||
return E_FAIL;
|
|
||||||
|
|
||||||
UInt64 complexity = 0;
|
|
||||||
file.IsStartPosDefined = true;
|
|
||||||
file.StartPos = 0;
|
|
||||||
for (UInt64 volumeIndex = 0; true; volumeIndex++)
|
|
||||||
{
|
|
||||||
UInt64 volSize;
|
|
||||||
RINOK(volumeCallback->GetVolumeSize(volumeIndex, &volSize));
|
|
||||||
UInt64 pureSize = COutArchive::GetVolPureSize(volSize, file.Name.Length(), true);
|
|
||||||
CMyComPtr<ISequentialOutStream> volumeStream;
|
|
||||||
RINOK(volumeCallback->GetVolumeStream(volumeIndex, &volumeStream));
|
|
||||||
|
|
||||||
COutArchive archive;
|
|
||||||
RINOK(archive.Create(volumeStream, true));
|
|
||||||
RINOK(archive.SkeepPrefixArchiveHeader());
|
|
||||||
|
|
||||||
CSequentialInStreamWithCRC *inCrcStreamSpec = new CSequentialInStreamWithCRC;
|
|
||||||
CMyComPtr<ISequentialInStream> inCrcStream = inCrcStreamSpec;
|
|
||||||
inCrcStreamSpec->Init(fileStream);
|
|
||||||
|
|
||||||
RINOK(WriteRange(inCrcStream, volumeStream, pureSize, updateCallback, complexity));
|
|
||||||
file.UnPackSize = inCrcStreamSpec->GetSize();
|
|
||||||
if (file.UnPackSize == 0)
|
|
||||||
break;
|
|
||||||
file.FileCRC = inCrcStreamSpec->GetCRC();
|
|
||||||
RINOK(WriteVolumeHeader(archive, file, options));
|
|
||||||
file.StartPos += file.UnPackSize;
|
|
||||||
if (file.UnPackSize < pureSize)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
class COutVolumeStream:
|
|
||||||
public ISequentialOutStream,
|
|
||||||
public CMyUnknownImp
|
|
||||||
{
|
|
||||||
int _volIndex;
|
|
||||||
UInt64 _volSize;
|
|
||||||
UInt64 _curPos;
|
|
||||||
CMyComPtr<ISequentialOutStream> _volumeStream;
|
|
||||||
COutArchive _archive;
|
|
||||||
CCRC _crc;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MY_UNKNOWN_IMP
|
|
||||||
|
|
||||||
CFileItem _file;
|
|
||||||
CUpdateOptions _options;
|
|
||||||
CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
|
|
||||||
void Init(IArchiveUpdateCallback2 *volumeCallback,
|
|
||||||
const UString &name)
|
|
||||||
{
|
|
||||||
_file.Name = name;
|
|
||||||
_file.IsStartPosDefined = true;
|
|
||||||
_file.StartPos = 0;
|
|
||||||
|
|
||||||
VolumeCallback = volumeCallback;
|
|
||||||
_volIndex = 0;
|
|
||||||
_volSize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT Flush();
|
|
||||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
};
|
|
||||||
|
|
||||||
HRESULT COutVolumeStream::Flush()
|
|
||||||
{
|
|
||||||
if (_volumeStream)
|
|
||||||
{
|
|
||||||
_file.UnPackSize = _curPos;
|
|
||||||
_file.FileCRC = _crc.GetDigest();
|
|
||||||
RINOK(WriteVolumeHeader(_archive, _file, _options));
|
|
||||||
_archive.Close();
|
|
||||||
_volumeStream.Release();
|
|
||||||
_file.StartPos += _file.UnPackSize;
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP COutVolumeStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
if(processedSize != NULL)
|
|
||||||
*processedSize = 0;
|
|
||||||
while(size > 0)
|
|
||||||
{
|
|
||||||
if (!_volumeStream)
|
|
||||||
{
|
|
||||||
RINOK(VolumeCallback->GetVolumeSize(_volIndex, &_volSize));
|
|
||||||
RINOK(VolumeCallback->GetVolumeStream(_volIndex, &_volumeStream));
|
|
||||||
_volIndex++;
|
|
||||||
_curPos = 0;
|
|
||||||
RINOK(_archive.Create(_volumeStream, true));
|
|
||||||
RINOK(_archive.SkeepPrefixArchiveHeader());
|
|
||||||
_crc.Init();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
UInt64 pureSize = COutArchive::GetVolPureSize(_volSize, _file.Name.Length());
|
|
||||||
UInt32 curSize = (UInt32)MyMin(UInt64(size), pureSize - _curPos);
|
|
||||||
|
|
||||||
_crc.Update(data, curSize);
|
|
||||||
UInt32 realProcessed;
|
|
||||||
RINOK(_volumeStream->Write(data, curSize, &realProcessed))
|
|
||||||
data = (void *)((Byte *)data + realProcessed);
|
|
||||||
size -= realProcessed;
|
|
||||||
if(processedSize != NULL)
|
|
||||||
*processedSize += realProcessed;
|
|
||||||
_curPos += realProcessed;
|
|
||||||
if (realProcessed != curSize && realProcessed == 0)
|
|
||||||
return E_FAIL;
|
|
||||||
if (_curPos == pureSize)
|
|
||||||
{
|
|
||||||
RINOK(Flush());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
HRESULT Update(
|
HRESULT Update(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
IInStream *inStream,
|
IInStream *inStream,
|
||||||
const CArchiveDatabaseEx *database,
|
const CArchiveDatabaseEx *db,
|
||||||
const CObjectVector<CUpdateItem> &updateItems,
|
const CObjectVector<CUpdateItem> &updateItems,
|
||||||
|
COutArchive &archive,
|
||||||
|
CArchiveDatabase &newDatabase,
|
||||||
ISequentialOutStream *seqOutStream,
|
ISequentialOutStream *seqOutStream,
|
||||||
IArchiveUpdateCallback *updateCallback,
|
IArchiveUpdateCallback *updateCallback,
|
||||||
const CUpdateOptions &options)
|
const CUpdateOptions &options)
|
||||||
{
|
{
|
||||||
#ifdef _7Z_VOL
|
return Update2(
|
||||||
if (seqOutStream)
|
|
||||||
#endif
|
|
||||||
return Update2(
|
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
inStream, database, updateItems,
|
inStream, db, updateItems,
|
||||||
seqOutStream, updateCallback, options);
|
archive, newDatabase, seqOutStream, updateCallback, options);
|
||||||
#ifdef _7Z_VOL
|
|
||||||
if (options.VolumeMode)
|
|
||||||
return UpdateVolume(inStream, database, updateItems,
|
|
||||||
seqOutStream, updateCallback, options);
|
|
||||||
COutVolumeStream *volStreamSpec = new COutVolumeStream;
|
|
||||||
CMyComPtr<ISequentialOutStream> volStream = volStreamSpec;
|
|
||||||
CMyComPtr<IArchiveUpdateCallback2> volumeCallback;
|
|
||||||
RINOK(updateCallback->QueryInterface(IID_IArchiveUpdateCallback2, (void **)&volumeCallback));
|
|
||||||
if (!volumeCallback)
|
|
||||||
return E_NOTIMPL;
|
|
||||||
volStreamSpec->Init(volumeCallback, L"a.7z");
|
|
||||||
volStreamSpec->_options = options;
|
|
||||||
RINOK(Update2(inStream, database, updateItems,
|
|
||||||
volStream, updateCallback, options));
|
|
||||||
return volStreamSpec->Flush();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -14,38 +14,40 @@ namespace N7z {
|
|||||||
|
|
||||||
struct CUpdateItem
|
struct CUpdateItem
|
||||||
{
|
{
|
||||||
bool NewData;
|
|
||||||
bool NewProperties;
|
|
||||||
int IndexInArchive;
|
int IndexInArchive;
|
||||||
int IndexInClient;
|
int IndexInClient;
|
||||||
|
|
||||||
UInt32 Attributes;
|
UInt64 CTime;
|
||||||
FILETIME CreationTime;
|
UInt64 ATime;
|
||||||
FILETIME LastWriteTime;
|
UInt64 MTime;
|
||||||
FILETIME LastAccessTime;
|
|
||||||
|
|
||||||
UInt64 Size;
|
UInt64 Size;
|
||||||
UString Name;
|
UString Name;
|
||||||
|
|
||||||
|
UInt32 Attrib;
|
||||||
|
|
||||||
|
bool NewData;
|
||||||
|
bool NewProperties;
|
||||||
|
|
||||||
bool IsAnti;
|
bool IsAnti;
|
||||||
bool IsDirectory;
|
bool IsDir;
|
||||||
|
|
||||||
bool IsCreationTimeDefined;
|
bool AttribDefined;
|
||||||
bool IsLastWriteTimeDefined;
|
bool CTimeDefined;
|
||||||
bool IsLastAccessTimeDefined;
|
bool ATimeDefined;
|
||||||
bool AttributesAreDefined;
|
bool MTimeDefined;
|
||||||
|
|
||||||
bool HasStream() const
|
bool HasStream() const { return !IsDir && !IsAnti && Size != 0; }
|
||||||
{ return !IsDirectory && !IsAnti && Size != 0; }
|
|
||||||
CUpdateItem():
|
CUpdateItem():
|
||||||
IsAnti(false),
|
IsAnti(false),
|
||||||
AttributesAreDefined(false),
|
IsDir(false),
|
||||||
IsCreationTimeDefined(false),
|
AttribDefined(false),
|
||||||
IsLastWriteTimeDefined(false),
|
CTimeDefined(false),
|
||||||
IsLastAccessTimeDefined(false)
|
ATimeDefined(false),
|
||||||
|
MTimeDefined(false)
|
||||||
{}
|
{}
|
||||||
void SetDirectoryStatusFromAttributes()
|
void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); };
|
||||||
{ IsDirectory = ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); };
|
|
||||||
|
|
||||||
int GetExtensionPos() const;
|
int GetExtensionPos() const;
|
||||||
UString GetExtension() const;
|
UString GetExtension() const;
|
||||||
@@ -70,8 +72,10 @@ struct CUpdateOptions
|
|||||||
HRESULT Update(
|
HRESULT Update(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
IInStream *inStream,
|
IInStream *inStream,
|
||||||
const CArchiveDatabaseEx *database,
|
const CArchiveDatabaseEx *db,
|
||||||
const CObjectVector<CUpdateItem> &updateItems,
|
const CObjectVector<CUpdateItem> &updateItems,
|
||||||
|
COutArchive &archive,
|
||||||
|
CArchiveDatabase &newDatabase,
|
||||||
ISequentialOutStream *seqOutStream,
|
ISequentialOutStream *seqOutStream,
|
||||||
IArchiveUpdateCallback *updateCallback,
|
IArchiveUpdateCallback *updateCallback,
|
||||||
const CUpdateOptions &options);
|
const CUpdateOptions &options);
|
||||||
|
|||||||
Executable
+111
@@ -0,0 +1,111 @@
|
|||||||
|
PROG = 7z.dll
|
||||||
|
DEF_FILE = ../Archive.def
|
||||||
|
CFLAGS = $(CFLAGS) -I ../../../ \
|
||||||
|
-DCOMPRESS_MT \
|
||||||
|
-DEXTERNAL_CODECS \
|
||||||
|
|
||||||
|
LIBS = $(LIBS) oleaut32.lib user32.lib
|
||||||
|
|
||||||
|
AR_OBJS = \
|
||||||
|
$O\ArchiveExports.obj \
|
||||||
|
$O\DllExports.obj \
|
||||||
|
|
||||||
|
7Z_OBJS = \
|
||||||
|
$O\7zCompressionMode.obj \
|
||||||
|
$O\7zDecode.obj \
|
||||||
|
$O\7zEncode.obj \
|
||||||
|
$O\7zExtract.obj \
|
||||||
|
$O\7zFolderInStream.obj \
|
||||||
|
$O\7zFolderOutStream.obj \
|
||||||
|
$O\7zHandler.obj \
|
||||||
|
$O\7zHandlerOut.obj \
|
||||||
|
$O\7zHeader.obj \
|
||||||
|
$O\7zIn.obj \
|
||||||
|
$O\7zOut.obj \
|
||||||
|
$O\7zProperties.obj \
|
||||||
|
$O\7zSpecStream.obj \
|
||||||
|
$O\7zUpdate.obj \
|
||||||
|
$O\7zRegister.obj \
|
||||||
|
|
||||||
|
COMMON_OBJS = \
|
||||||
|
$O\CRC.obj \
|
||||||
|
$O\IntToString.obj \
|
||||||
|
$O\NewHandler.obj \
|
||||||
|
$O\MyString.obj \
|
||||||
|
$O\StringConvert.obj \
|
||||||
|
$O\StringToInt.obj \
|
||||||
|
$O\MyVector.obj \
|
||||||
|
|
||||||
|
WIN_OBJS = \
|
||||||
|
$O\DLL.obj \
|
||||||
|
$O\FileDir.obj \
|
||||||
|
$O\FileFind.obj \
|
||||||
|
$O\FileIO.obj \
|
||||||
|
$O\PropVariant.obj \
|
||||||
|
$O\Synchronization.obj \
|
||||||
|
$O\System.obj \
|
||||||
|
|
||||||
|
7ZIP_COMMON_OBJS = \
|
||||||
|
$O\CreateCoder.obj \
|
||||||
|
$O\InOutTempBuffer.obj \
|
||||||
|
$O\FilterCoder.obj \
|
||||||
|
$O\LimitedStreams.obj \
|
||||||
|
$O\LockedStream.obj \
|
||||||
|
$O\MethodId.obj \
|
||||||
|
$O\MethodProps.obj \
|
||||||
|
$O\OutBuffer.obj \
|
||||||
|
$O\ProgressUtils.obj \
|
||||||
|
$O\StreamBinder.obj \
|
||||||
|
$O\StreamObjects.obj \
|
||||||
|
$O\StreamUtils.obj \
|
||||||
|
$O\VirtThread.obj \
|
||||||
|
|
||||||
|
AR_COMMON_OBJS = \
|
||||||
|
$O\CoderMixer2.obj \
|
||||||
|
$O\CoderMixer2MT.obj \
|
||||||
|
$O\CrossThreadProgress.obj \
|
||||||
|
$O\HandlerOut.obj \
|
||||||
|
$O\InStreamWithCRC.obj \
|
||||||
|
$O\ItemNameUtils.obj \
|
||||||
|
$O\MultiStream.obj \
|
||||||
|
$O\OutStreamWithCRC.obj \
|
||||||
|
$O\ParseProperties.obj \
|
||||||
|
|
||||||
|
C_OBJS = \
|
||||||
|
$O\Alloc.obj \
|
||||||
|
$O\Threads.obj \
|
||||||
|
|
||||||
|
!include "../../Crc2.mak"
|
||||||
|
|
||||||
|
OBJS = \
|
||||||
|
$O\StdAfx.obj \
|
||||||
|
$(AR_OBJS) \
|
||||||
|
$(7Z_OBJS) \
|
||||||
|
$(COMMON_OBJS) \
|
||||||
|
$(WIN_OBJS) \
|
||||||
|
$(7ZIP_COMMON_OBJS) \
|
||||||
|
$(AR_COMMON_OBJS) \
|
||||||
|
$O\CopyCoder.obj \
|
||||||
|
$(C_OBJS) \
|
||||||
|
$(CRC_OBJS) \
|
||||||
|
$O\resource.res
|
||||||
|
|
||||||
|
!include "../../../Build.mak"
|
||||||
|
|
||||||
|
$(AR_OBJS): ../$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(7Z_OBJS): $(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(COMMON_OBJS): ../../../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(WIN_OBJS): ../../../Windows/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(AR_COMMON_OBJS): ../Common/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp
|
||||||
|
$(COMPL)
|
||||||
|
$(C_OBJS): ../../../../C/$(*B).c
|
||||||
|
$(COMPL_O2)
|
||||||
|
!include "../../Crc.mak"
|
||||||
Executable
+11
@@ -0,0 +1,11 @@
|
|||||||
|
#include "../../MyVersionInfo.rc"
|
||||||
|
|
||||||
|
MY_VERSION_INFO_DLL("7z Plugin", "7z")
|
||||||
|
|
||||||
|
0 ICON "../Icons/7z.ico"
|
||||||
|
|
||||||
|
STRINGTABLE
|
||||||
|
BEGIN
|
||||||
|
100 "7z:0"
|
||||||
|
END
|
||||||
|
|
||||||
@@ -13,14 +13,14 @@
|
|||||||
|
|
||||||
static const unsigned int kNumArcsMax = 32;
|
static const unsigned int kNumArcsMax = 32;
|
||||||
static unsigned int g_NumArcs = 0;
|
static unsigned int g_NumArcs = 0;
|
||||||
static const CArcInfo *g_Arcs[kNumArcsMax];
|
static const CArcInfo *g_Arcs[kNumArcsMax];
|
||||||
void RegisterArc(const CArcInfo *arcInfo)
|
void RegisterArc(const CArcInfo *arcInfo)
|
||||||
{
|
{
|
||||||
if (g_NumArcs < kNumArcsMax)
|
if (g_NumArcs < kNumArcsMax)
|
||||||
g_Arcs[g_NumArcs++] = arcInfo;
|
g_Arcs[g_NumArcs++] = arcInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_GUID(CLSID_CArchiveHandler,
|
DEFINE_GUID(CLSID_CArchiveHandler,
|
||||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
|
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
|
||||||
|
|
||||||
#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5])
|
#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5])
|
||||||
|
|||||||
@@ -1,311 +0,0 @@
|
|||||||
// ArjHandler.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "Common/Defs.h"
|
|
||||||
#include "Common/StringConvert.h"
|
|
||||||
#include "Common/ComTry.h"
|
|
||||||
|
|
||||||
#include "Windows/Time.h"
|
|
||||||
#include "Windows/PropVariant.h"
|
|
||||||
|
|
||||||
#include "ArjHandler.h"
|
|
||||||
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
|
|
||||||
#include "../../Common/StreamObjects.h"
|
|
||||||
#include "../../Common/ProgressUtils.h"
|
|
||||||
#include "../../Common/LimitedStreams.h"
|
|
||||||
|
|
||||||
#include "../../Compress/Copy/CopyCoder.h"
|
|
||||||
#include "../../Compress/Arj/ArjDecoder1.h"
|
|
||||||
#include "../../Compress/Arj/ArjDecoder2.h"
|
|
||||||
|
|
||||||
#include "../Common/ItemNameUtils.h"
|
|
||||||
#include "../Common/OutStreamWithCRC.h"
|
|
||||||
|
|
||||||
using namespace NWindows;
|
|
||||||
using namespace NTime;
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NArj{
|
|
||||||
|
|
||||||
const wchar_t *kHostOS[] =
|
|
||||||
{
|
|
||||||
L"MSDOS",
|
|
||||||
L"PRIMOS",
|
|
||||||
L"Unix",
|
|
||||||
L"AMIGA",
|
|
||||||
L"Mac",
|
|
||||||
L"OS/2",
|
|
||||||
L"APPLE GS",
|
|
||||||
L"Atari ST",
|
|
||||||
L"Next",
|
|
||||||
L"VAX VMS",
|
|
||||||
L"WIN95"
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
|
|
||||||
|
|
||||||
const wchar_t *kUnknownOS = L"Unknown";
|
|
||||||
|
|
||||||
|
|
||||||
STATPROPSTG kProps[] =
|
|
||||||
{
|
|
||||||
{ NULL, kpidPath, VT_BSTR},
|
|
||||||
{ NULL, kpidIsFolder, VT_BOOL},
|
|
||||||
{ NULL, kpidSize, VT_UI8},
|
|
||||||
{ NULL, kpidPackedSize, VT_UI8},
|
|
||||||
{ NULL, kpidLastWriteTime, VT_FILETIME},
|
|
||||||
{ NULL, kpidAttributes, VT_UI4},
|
|
||||||
{ NULL, kpidEncrypted, VT_BOOL},
|
|
||||||
{ NULL, kpidCRC, VT_UI4},
|
|
||||||
{ NULL, kpidMethod, VT_UI1},
|
|
||||||
// { NULL, kpidUnpackVer, VT_UI1},
|
|
||||||
{ NULL, kpidHostOS, VT_BSTR}
|
|
||||||
};
|
|
||||||
|
|
||||||
IMP_IInArchive_Props
|
|
||||||
IMP_IInArchive_ArcProps_NO
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
|
||||||
{
|
|
||||||
*numItems = _items.Size();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
NWindows::NCOM::CPropVariant prop;
|
|
||||||
const CItemEx &item = _items[index];
|
|
||||||
switch(propID)
|
|
||||||
{
|
|
||||||
case kpidPath: prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break;
|
|
||||||
case kpidIsFolder: prop = item.IsDirectory(); break;
|
|
||||||
case kpidSize: prop = item.Size; break;
|
|
||||||
case kpidPackedSize: prop = item.PackSize; break;
|
|
||||||
case kpidAttributes: prop = item.GetWinAttributes(); break;
|
|
||||||
case kpidEncrypted: prop = item.IsEncrypted(); break;
|
|
||||||
case kpidCRC: prop = item.FileCRC; break;
|
|
||||||
case kpidMethod: prop = item.Method; break;
|
|
||||||
case kpidHostOS: prop = (item.HostOS < kNumHostOSes) ? (kHostOS[item.HostOS]) : kUnknownOS; break;
|
|
||||||
case kpidLastWriteTime:
|
|
||||||
{
|
|
||||||
FILETIME localFileTime, utcFileTime;
|
|
||||||
if (DosTimeToFileTime(item.ModifiedTime, localFileTime))
|
|
||||||
{
|
|
||||||
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
|
|
||||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
|
|
||||||
prop = utcFileTime;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prop.Detach(value);
|
|
||||||
return S_OK;
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|
||||||
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_items.Clear();
|
|
||||||
CInArchive archive;
|
|
||||||
if(!archive.Open(inStream, maxCheckStartPosition))
|
|
||||||
return S_FALSE;
|
|
||||||
if (callback != NULL)
|
|
||||||
{
|
|
||||||
RINOK(callback->SetTotal(NULL, NULL));
|
|
||||||
UInt64 numFiles = _items.Size();
|
|
||||||
RINOK(callback->SetCompleted(&numFiles, NULL));
|
|
||||||
}
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
CItemEx item;
|
|
||||||
bool filled;
|
|
||||||
HRESULT result = archive.GetNextItem(filled, item);
|
|
||||||
if (result == S_FALSE)
|
|
||||||
return S_FALSE;
|
|
||||||
if (result != S_OK)
|
|
||||||
return S_FALSE;
|
|
||||||
if (!filled)
|
|
||||||
break;
|
|
||||||
_items.Add(item);
|
|
||||||
archive.IncreaseRealPosition(item.PackSize);
|
|
||||||
if (callback != NULL)
|
|
||||||
{
|
|
||||||
UInt64 numFiles = _items.Size();
|
|
||||||
RINOK(callback->SetCompleted(&numFiles, NULL));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_stream = inStream;
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
COM_TRY_END
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Close()
|
|
||||||
{
|
|
||||||
_items.Clear();
|
|
||||||
_stream.Release();
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// CHandler::DecompressItems
|
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|
||||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
|
||||||
{
|
|
||||||
COM_TRY_BEGIN
|
|
||||||
bool testMode = (testModeSpec != 0);
|
|
||||||
UInt64 totalUnPacked = 0, totalPacked = 0;
|
|
||||||
bool allFilesMode = (numItems == UInt32(-1));
|
|
||||||
if (allFilesMode)
|
|
||||||
numItems = _items.Size();
|
|
||||||
if(numItems == 0)
|
|
||||||
return S_OK;
|
|
||||||
UInt32 i;
|
|
||||||
for(i = 0; i < numItems; i++)
|
|
||||||
{
|
|
||||||
const CItemEx &item = _items[allFilesMode ? i : indices[i]];
|
|
||||||
totalUnPacked += item.Size;
|
|
||||||
totalPacked += item.PackSize;
|
|
||||||
}
|
|
||||||
extractCallback->SetTotal(totalUnPacked);
|
|
||||||
|
|
||||||
UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
|
|
||||||
UInt64 currentItemUnPacked, currentItemPacked;
|
|
||||||
|
|
||||||
CMyComPtr<ICompressCoder> arj1Decoder;
|
|
||||||
CMyComPtr<ICompressCoder> arj2Decoder;
|
|
||||||
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++, currentTotalUnPacked += currentItemUnPacked,
|
|
||||||
currentTotalPacked += currentItemPacked)
|
|
||||||
{
|
|
||||||
lps->InSize = currentTotalPacked;
|
|
||||||
lps->OutSize = currentTotalUnPacked;
|
|
||||||
RINOK(lps->SetCur());
|
|
||||||
|
|
||||||
currentItemUnPacked = currentItemPacked = 0;
|
|
||||||
|
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
|
||||||
Int32 askMode = testMode ?
|
|
||||||
NExtract::NAskMode::kTest :
|
|
||||||
NExtract::NAskMode::kExtract;
|
|
||||||
Int32 index = allFilesMode ? i : indices[i];
|
|
||||||
const CItemEx &item = _items[index];
|
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
|
||||||
|
|
||||||
if(item.IsDirectory())
|
|
||||||
{
|
|
||||||
// if (!testMode)
|
|
||||||
{
|
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
|
||||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!testMode && (!realOutStream))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
RINOK(extractCallback->PrepareOperation(askMode));
|
|
||||||
currentItemUnPacked = item.Size;
|
|
||||||
currentItemPacked = item.PackSize;
|
|
||||||
|
|
||||||
{
|
|
||||||
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
|
|
||||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
|
||||||
outStreamSpec->SetStream(realOutStream);
|
|
||||||
outStreamSpec->Init();
|
|
||||||
realOutStream.Release();
|
|
||||||
|
|
||||||
streamSpec->Init(item.PackSize);
|
|
||||||
|
|
||||||
UInt64 pos;
|
|
||||||
_stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos);
|
|
||||||
|
|
||||||
HRESULT result = S_OK;
|
|
||||||
Int32 opRes = NExtract::NOperationResult::kOK;
|
|
||||||
|
|
||||||
if (item.IsEncrypted())
|
|
||||||
{
|
|
||||||
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch(item.Method)
|
|
||||||
{
|
|
||||||
case NFileHeader::NCompressionMethod::kStored:
|
|
||||||
{
|
|
||||||
result = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
|
|
||||||
if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize)
|
|
||||||
result = S_FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NFileHeader::NCompressionMethod::kCompressed1a:
|
|
||||||
case NFileHeader::NCompressionMethod::kCompressed1b:
|
|
||||||
case NFileHeader::NCompressionMethod::kCompressed1c:
|
|
||||||
{
|
|
||||||
if (!arj1Decoder)
|
|
||||||
arj1Decoder = new NCompress::NArj::NDecoder1::CCoder;
|
|
||||||
result = arj1Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NFileHeader::NCompressionMethod::kCompressed2:
|
|
||||||
{
|
|
||||||
if (!arj2Decoder)
|
|
||||||
arj2Decoder = new NCompress::NArj::NDecoder2::CCoder;
|
|
||||||
result = arj2Decoder->Code(inStream, outStream, NULL, ¤tItemUnPacked, progress);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (opRes == NExtract::NOperationResult::kOK)
|
|
||||||
{
|
|
||||||
if (result == S_FALSE)
|
|
||||||
opRes = NExtract::NOperationResult::kDataError;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RINOK(result);
|
|
||||||
opRes = (outStreamSpec->GetCRC() == item.FileCRC) ?
|
|
||||||
NExtract::NOperationResult::kOK:
|
|
||||||
NExtract::NOperationResult::kCRCError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outStream.Release();
|
|
||||||
RINOK(extractCallback->SetOperationResult(opRes));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
COM_TRY_END
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
// Archive/Arj/Header.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_ARJ_HEADER_H
|
|
||||||
#define __ARCHIVE_ARJ_HEADER_H
|
|
||||||
|
|
||||||
#include "Common/Types.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NArj {
|
|
||||||
|
|
||||||
const int kMaxBlockSize = 2600;
|
|
||||||
|
|
||||||
namespace NSignature
|
|
||||||
{
|
|
||||||
const Byte kSig0 = 0x60;
|
|
||||||
const Byte kSig1 = 0xEA;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
struct CArchiveHeader
|
|
||||||
{
|
|
||||||
// UInt16 BasicHeaderSize;
|
|
||||||
Byte FirstHeaderSize;
|
|
||||||
Byte Version;
|
|
||||||
Byte ExtractVersion;
|
|
||||||
Byte HostOS;
|
|
||||||
Byte Flags;
|
|
||||||
Byte SecuryVersion;
|
|
||||||
Byte FileType;
|
|
||||||
Byte Reserved;
|
|
||||||
UInt32 CreatedTime;
|
|
||||||
UInt32 ModifiedTime;
|
|
||||||
UInt32 ArchiveSize;
|
|
||||||
UInt32 SecurityEnvelopeFilePosition;
|
|
||||||
UInt16 FilespecPositionInFilename;
|
|
||||||
UInt16 LengthOfSecurityEnvelopeSata;
|
|
||||||
Byte EncryptionVersion;
|
|
||||||
Byte LastChapter;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace NFileHeader
|
|
||||||
{
|
|
||||||
namespace NCompressionMethod
|
|
||||||
{
|
|
||||||
enum EType
|
|
||||||
{
|
|
||||||
kStored = 0,
|
|
||||||
kCompressed1a = 1,
|
|
||||||
kCompressed1b = 2,
|
|
||||||
kCompressed1c = 3,
|
|
||||||
kCompressed2 = 4,
|
|
||||||
kNoDataNoCRC = 8,
|
|
||||||
kNoData = 9
|
|
||||||
};
|
|
||||||
}
|
|
||||||
namespace NFileType
|
|
||||||
{
|
|
||||||
enum EType
|
|
||||||
{
|
|
||||||
kBinary = 0,
|
|
||||||
k7BitText = 1,
|
|
||||||
kDirectory = 3,
|
|
||||||
kVolumeLablel = 4,
|
|
||||||
kChapterLabel = 5
|
|
||||||
};
|
|
||||||
}
|
|
||||||
namespace NFlags
|
|
||||||
{
|
|
||||||
const Byte kGarbled = 1;
|
|
||||||
const Byte kVolume = 4;
|
|
||||||
const Byte kExtFile = 8;
|
|
||||||
const Byte kPathSym = 0x10;
|
|
||||||
const Byte kBackup= 0x20;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
struct CHeader
|
|
||||||
{
|
|
||||||
Byte FirstHeaderSize;
|
|
||||||
Byte Version;
|
|
||||||
Byte ExtractVersion;
|
|
||||||
Byte HostOS;
|
|
||||||
Byte Flags;
|
|
||||||
Byte Method;
|
|
||||||
Byte FileType;
|
|
||||||
Byte Reserved;
|
|
||||||
UInt32 ModifiedTime;
|
|
||||||
UInt32 PackSize;
|
|
||||||
UInt32 Size;
|
|
||||||
UInt32 FileCRC;
|
|
||||||
UInt16 FilespecPositionInFilename;
|
|
||||||
UInt16 FileAccessMode;
|
|
||||||
Byte FirstChapter;
|
|
||||||
Byte LastChapter;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace NHostOS
|
|
||||||
{
|
|
||||||
enum EEnum
|
|
||||||
{
|
|
||||||
kMSDOS = 0, // filesystem used by MS-DOS, OS/2, Win32
|
|
||||||
// pkarj 2.50 (FAT / VFAT / FAT32 file systems)
|
|
||||||
kPRIMOS = 1,
|
|
||||||
kUnix = 2, // VAX/VMS
|
|
||||||
kAMIGA = 3,
|
|
||||||
kMac = 4,
|
|
||||||
kOS_2 = 5, // what if it's a minix filesystem? [cjh]
|
|
||||||
kAPPLE_GS = 6, // filesystem used by OS/2 (and NT 3.x)
|
|
||||||
kAtari_ST = 7,
|
|
||||||
kNext = 8,
|
|
||||||
kVAX_VMS = 9,
|
|
||||||
kWIN95 = 10
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,287 +0,0 @@
|
|||||||
// Archive/arj/InEngine.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "Common/StringConvert.h"
|
|
||||||
#include "Common/Buffer.h"
|
|
||||||
|
|
||||||
#include "../../Common/StreamUtils.h"
|
|
||||||
|
|
||||||
#include "ArjIn.h"
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#include "../../../../C/7zCrc.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NArj {
|
|
||||||
|
|
||||||
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
|
|
||||||
{
|
|
||||||
size_t realProcessedSize = size;
|
|
||||||
HRESULT result = ReadStream(_stream, data, &realProcessedSize);
|
|
||||||
if (processedSize != NULL)
|
|
||||||
*processedSize = (UInt32)realProcessedSize;
|
|
||||||
IncreasePositionValue(realProcessedSize);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline UInt16 GetUInt16FromMemLE(const Byte *p)
|
|
||||||
{
|
|
||||||
return (UInt16)(p[0] | (((UInt16)p[1]) << 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline UInt32 GetUInt32FromMemLE(const Byte *p)
|
|
||||||
{
|
|
||||||
return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool TestMarkerCandidate(const void *testBytes, UInt32 maxSize)
|
|
||||||
{
|
|
||||||
if (maxSize < 2 + 2 + 4)
|
|
||||||
return false;
|
|
||||||
const Byte *block = ((const Byte *)(testBytes));
|
|
||||||
if (block[0] != NSignature::kSig0 || block[1] != NSignature::kSig1)
|
|
||||||
return false;
|
|
||||||
UInt32 blockSize = GetUInt16FromMemLE(block + 2);
|
|
||||||
if (maxSize < 2 + 2 + blockSize + 4)
|
|
||||||
return false;
|
|
||||||
block += 4;
|
|
||||||
if (blockSize == 0 || blockSize > 2600)
|
|
||||||
return false;
|
|
||||||
UInt32 crcFromFile = GetUInt32FromMemLE(block + blockSize);
|
|
||||||
return (crcFromFile == CrcCalc(block, blockSize));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
|
|
||||||
{
|
|
||||||
// _archiveInfo.StartPosition = 0;
|
|
||||||
_position = _streamStartPosition;
|
|
||||||
if(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL) != S_OK)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const int kMarkerSizeMax = 2 + 2 + kMaxBlockSize + 4;
|
|
||||||
|
|
||||||
CByteBuffer byteBuffer;
|
|
||||||
static const UInt32 kSearchMarkerBufferSize = 0x10000;
|
|
||||||
byteBuffer.SetCapacity(kSearchMarkerBufferSize);
|
|
||||||
Byte *buffer = byteBuffer;
|
|
||||||
|
|
||||||
UInt32 processedSize;
|
|
||||||
ReadBytes(buffer, kMarkerSizeMax, &processedSize);
|
|
||||||
if (processedSize == 0)
|
|
||||||
return false;
|
|
||||||
if (TestMarkerCandidate(buffer, processedSize))
|
|
||||||
{
|
|
||||||
_position = _streamStartPosition;
|
|
||||||
if(_stream->Seek(_position, STREAM_SEEK_SET, NULL) != S_OK)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 numBytesPrev = processedSize - 1;
|
|
||||||
memmove(buffer, buffer + 1, numBytesPrev);
|
|
||||||
UInt64 curTestPos = _streamStartPosition + 1;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
if (searchHeaderSizeLimit != NULL)
|
|
||||||
if (curTestPos - _streamStartPosition > *searchHeaderSizeLimit)
|
|
||||||
return false;
|
|
||||||
UInt32 numReadBytes = kSearchMarkerBufferSize - numBytesPrev;
|
|
||||||
ReadBytes(buffer + numBytesPrev, numReadBytes, &processedSize);
|
|
||||||
UInt32 numBytesInBuffer = numBytesPrev + processedSize;
|
|
||||||
if (numBytesInBuffer < 1)
|
|
||||||
return false;
|
|
||||||
UInt32 numTests = numBytesInBuffer;
|
|
||||||
for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
|
|
||||||
{
|
|
||||||
if (TestMarkerCandidate(buffer + pos, numBytesInBuffer - pos))
|
|
||||||
{
|
|
||||||
// _archiveInfo.StartPosition = curTestPos;
|
|
||||||
_position = curTestPos;
|
|
||||||
if(_stream->Seek(_position, STREAM_SEEK_SET, NULL) != S_OK)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
numBytesPrev = numBytesInBuffer - numTests;
|
|
||||||
memmove(buffer, buffer + numTests, numBytesPrev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInArchive::IncreasePositionValue(UInt64 addValue)
|
|
||||||
{
|
|
||||||
_position += addValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInArchive::IncreaseRealPosition(UInt64 addValue)
|
|
||||||
{
|
|
||||||
if(_stream->Seek(addValue, STREAM_SEEK_CUR, &_position) != S_OK)
|
|
||||||
throw CInArchiveException(CInArchiveException::kSeekStreamError);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CInArchive::ReadBytesAndTestSize(void *data, UInt32 size)
|
|
||||||
{
|
|
||||||
UInt32 realProcessedSize;
|
|
||||||
if(ReadBytes(data, size, &realProcessedSize) != S_OK)
|
|
||||||
throw CInArchiveException(CInArchiveException::kReadStreamError);
|
|
||||||
return (realProcessedSize == size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInArchive::SafeReadBytes(void *data, UInt32 size)
|
|
||||||
{
|
|
||||||
if(!ReadBytesAndTestSize(data, size))
|
|
||||||
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
|
||||||
}
|
|
||||||
|
|
||||||
Byte CInArchive::SafeReadByte()
|
|
||||||
{
|
|
||||||
Byte b;
|
|
||||||
SafeReadBytes(&b, 1);
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt16 CInArchive::SafeReadUInt16()
|
|
||||||
{
|
|
||||||
UInt16 value = 0;
|
|
||||||
for (int i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
Byte b = SafeReadByte();
|
|
||||||
value |= (UInt16(b) << (8 * i));
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 CInArchive::SafeReadUInt32()
|
|
||||||
{
|
|
||||||
UInt32 value = 0;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
Byte b = SafeReadByte();
|
|
||||||
value |= (UInt32(b) << (8 * i));
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CInArchive::ReadBlock()
|
|
||||||
{
|
|
||||||
_blockPos = 0;
|
|
||||||
_blockSize = SafeReadUInt16();
|
|
||||||
if (_blockSize == 0 || _blockSize > kMaxBlockSize)
|
|
||||||
return false;
|
|
||||||
SafeReadBytes(_block, _blockSize);
|
|
||||||
UInt32 crcFromFile = SafeReadUInt32();
|
|
||||||
if (crcFromFile != CrcCalc(_block, _blockSize))
|
|
||||||
throw CInArchiveException(CInArchiveException::kCRCError);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CInArchive::ReadBlock2()
|
|
||||||
{
|
|
||||||
Byte id[2];
|
|
||||||
ReadBytesAndTestSize(id, 2);
|
|
||||||
if (id[0] != NSignature::kSig0 || id[1] != NSignature::kSig1)
|
|
||||||
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
|
|
||||||
return ReadBlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit)
|
|
||||||
{
|
|
||||||
_stream = inStream;
|
|
||||||
if(_stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition) != S_OK)
|
|
||||||
return false;
|
|
||||||
_position = _streamStartPosition;
|
|
||||||
if (!FindAndReadMarker(searchHeaderSizeLimit))
|
|
||||||
return false;
|
|
||||||
if (!ReadBlock2())
|
|
||||||
return false;
|
|
||||||
for (;;)
|
|
||||||
if (!ReadBlock())
|
|
||||||
break;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInArchive::Close()
|
|
||||||
{
|
|
||||||
_stream.Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CInArchive::ThrowIncorrectArchiveException()
|
|
||||||
{
|
|
||||||
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
|
|
||||||
}
|
|
||||||
|
|
||||||
Byte CInArchive::ReadByte()
|
|
||||||
{
|
|
||||||
if (_blockPos >= _blockSize)
|
|
||||||
ThrowIncorrectArchiveException();
|
|
||||||
return _block[_blockPos++];
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt16 CInArchive::ReadUInt16()
|
|
||||||
{
|
|
||||||
UInt16 value = 0;
|
|
||||||
for (int i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
Byte b = ReadByte();
|
|
||||||
value |= (UInt16(b) << (8 * i));
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 CInArchive::ReadUInt32()
|
|
||||||
{
|
|
||||||
UInt32 value = 0;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
Byte b = ReadByte();
|
|
||||||
value |= (UInt32(b) << (8 * i));
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
|
|
||||||
{
|
|
||||||
filled = false;
|
|
||||||
if (!ReadBlock2())
|
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
Byte firstHeaderSize = ReadByte();
|
|
||||||
item.Version = ReadByte();
|
|
||||||
item.ExtractVersion = ReadByte();
|
|
||||||
item.HostOS = ReadByte();
|
|
||||||
item.Flags = ReadByte();
|
|
||||||
item.Method = ReadByte();
|
|
||||||
item.FileType = ReadByte();
|
|
||||||
ReadByte(); // Reserved
|
|
||||||
item.ModifiedTime = ReadUInt32();
|
|
||||||
item.PackSize = ReadUInt32();
|
|
||||||
item.Size = ReadUInt32();
|
|
||||||
item.FileCRC = ReadUInt32();
|
|
||||||
ReadUInt16(); // FilespecPositionInFilename
|
|
||||||
item.FileAccessMode = ReadUInt16();
|
|
||||||
ReadByte(); // FirstChapter
|
|
||||||
ReadByte(); // LastChapter
|
|
||||||
|
|
||||||
/*
|
|
||||||
UInt32 extraData;
|
|
||||||
if ((header.Flags & NFileHeader::NFlags::kExtFile) != 0)
|
|
||||||
extraData = GetUInt32FromMemLE(_block + pos);
|
|
||||||
*/
|
|
||||||
_blockPos = firstHeaderSize;
|
|
||||||
|
|
||||||
for (; _blockPos < _blockSize;)
|
|
||||||
item.Name += (char)ReadByte();
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
if (!ReadBlock())
|
|
||||||
break;
|
|
||||||
|
|
||||||
item.DataPosition = _position;
|
|
||||||
|
|
||||||
filled = true;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
// Archive/ArjIn.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_ARJIN_H
|
|
||||||
#define __ARCHIVE_ARJIN_H
|
|
||||||
|
|
||||||
#include "Common/MyCom.h"
|
|
||||||
#include "../../IStream.h"
|
|
||||||
|
|
||||||
#include "ArjItem.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NArj {
|
|
||||||
|
|
||||||
class CInArchiveException
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum CCauseType
|
|
||||||
{
|
|
||||||
kUnexpectedEndOfArchive = 0,
|
|
||||||
kCRCError,
|
|
||||||
kIncorrectArchive,
|
|
||||||
kReadStreamError,
|
|
||||||
kSeekStreamError
|
|
||||||
}
|
|
||||||
Cause;
|
|
||||||
CInArchiveException(CCauseType cause): Cause(cause) {};
|
|
||||||
};
|
|
||||||
|
|
||||||
class CProgressVirt
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CInArchive
|
|
||||||
{
|
|
||||||
CMyComPtr<IInStream> _stream;
|
|
||||||
UInt64 _streamStartPosition;
|
|
||||||
UInt64 _position;
|
|
||||||
UInt16 _blockSize;
|
|
||||||
Byte _block[kMaxBlockSize];
|
|
||||||
UInt32 _blockPos;
|
|
||||||
|
|
||||||
|
|
||||||
bool FindAndReadMarker(const UInt64 *searchHeaderSizeLimit);
|
|
||||||
|
|
||||||
bool ReadBlock();
|
|
||||||
bool ReadBlock2();
|
|
||||||
|
|
||||||
Byte ReadByte();
|
|
||||||
UInt16 ReadUInt16();
|
|
||||||
UInt32 ReadUInt32();
|
|
||||||
|
|
||||||
HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize);
|
|
||||||
bool ReadBytesAndTestSize(void *data, UInt32 size);
|
|
||||||
void SafeReadBytes(void *data, UInt32 size);
|
|
||||||
Byte SafeReadByte();
|
|
||||||
UInt16 SafeReadUInt16();
|
|
||||||
UInt32 SafeReadUInt32();
|
|
||||||
|
|
||||||
void IncreasePositionValue(UInt64 addValue);
|
|
||||||
void ThrowIncorrectArchiveException();
|
|
||||||
|
|
||||||
public:
|
|
||||||
HRESULT GetNextItem(bool &filled, CItemEx &item);
|
|
||||||
|
|
||||||
bool Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit);
|
|
||||||
void Close();
|
|
||||||
|
|
||||||
void IncreaseRealPosition(UInt64 addValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
// Archive/ArjItem.h
|
|
||||||
|
|
||||||
#ifndef __ARCHIVE_ARJ_ITEM_H
|
|
||||||
#define __ARCHIVE_ARJ_ITEM_H
|
|
||||||
|
|
||||||
#include "Common/Types.h"
|
|
||||||
#include "Common/MyString.h"
|
|
||||||
#include "ArjHeader.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
|
||||||
namespace NArj {
|
|
||||||
|
|
||||||
struct CVersion
|
|
||||||
{
|
|
||||||
Byte Version;
|
|
||||||
Byte HostOS;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool operator==(const CVersion &v1, const CVersion &v2)
|
|
||||||
{ return (v1.Version == v2.Version) && (v1.HostOS == v2.HostOS); }
|
|
||||||
inline bool operator!=(const CVersion &v1, const CVersion &v2)
|
|
||||||
{ return !(v1 == v2); }
|
|
||||||
|
|
||||||
class CItem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Byte Version;
|
|
||||||
Byte ExtractVersion;
|
|
||||||
Byte HostOS;
|
|
||||||
Byte Flags;
|
|
||||||
Byte Method;
|
|
||||||
Byte FileType;
|
|
||||||
UInt32 ModifiedTime;
|
|
||||||
UInt32 PackSize;
|
|
||||||
UInt32 Size;
|
|
||||||
UInt32 FileCRC;
|
|
||||||
|
|
||||||
// UInt16 FilespecPositionInFilename;
|
|
||||||
UInt16 FileAccessMode;
|
|
||||||
// Byte FirstChapter;
|
|
||||||
// Byte LastChapter;
|
|
||||||
|
|
||||||
AString Name;
|
|
||||||
|
|
||||||
bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kGarbled) != 0; }
|
|
||||||
bool IsDirectory() const { return (FileType == NFileHeader::NFileType::kDirectory); }
|
|
||||||
UInt32 GetWinAttributes() const
|
|
||||||
{
|
|
||||||
UInt32 winAtrributes;
|
|
||||||
switch(HostOS)
|
|
||||||
{
|
|
||||||
case NFileHeader::NHostOS::kMSDOS:
|
|
||||||
case NFileHeader::NHostOS::kWIN95:
|
|
||||||
winAtrributes = FileAccessMode;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
winAtrributes = 0;
|
|
||||||
}
|
|
||||||
if (IsDirectory())
|
|
||||||
winAtrributes |= FILE_ATTRIBUTE_DIRECTORY;
|
|
||||||
return winAtrributes;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CItemEx: public CItem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
UInt64 DataPosition;
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
// ArjRegister.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
|
|
||||||
#include "../../Common/RegisterArc.h"
|
|
||||||
|
|
||||||
#include "ArjHandler.h"
|
|
||||||
static IInArchive *CreateArc() { return new NArchive::NArj::CHandler; }
|
|
||||||
|
|
||||||
static CArcInfo g_ArcInfo =
|
|
||||||
{ L"Arj", L"arj", 0, 4, { 0x60, 0xEA }, 2, false, CreateArc, 0 };
|
|
||||||
|
|
||||||
REGISTER_ARC(Arj)
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// StdAfx.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
Executable
+792
@@ -0,0 +1,792 @@
|
|||||||
|
// ArjHandler.cpp
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "Common/ComTry.h"
|
||||||
|
#include "Common/StringConvert.h"
|
||||||
|
|
||||||
|
#include "Windows/PropVariant.h"
|
||||||
|
#include "Windows/Time.h"
|
||||||
|
|
||||||
|
#include "../../../C/CpuArch.h"
|
||||||
|
|
||||||
|
#include "../Common/LimitedStreams.h"
|
||||||
|
#include "../Common/ProgressUtils.h"
|
||||||
|
#include "../Common/RegisterArc.h"
|
||||||
|
#include "../Common/StreamObjects.h"
|
||||||
|
#include "../Common/StreamUtils.h"
|
||||||
|
|
||||||
|
#include "../Compress/Arj/ArjDecoder1.h"
|
||||||
|
#include "../Compress/Arj/ArjDecoder2.h"
|
||||||
|
#include "../Compress/Copy/CopyCoder.h"
|
||||||
|
|
||||||
|
#include "IArchive.h"
|
||||||
|
|
||||||
|
#include "Common/ItemNameUtils.h"
|
||||||
|
#include "Common/OutStreamWithCRC.h"
|
||||||
|
|
||||||
|
using namespace NWindows;
|
||||||
|
|
||||||
|
#define Get16(p) GetUi16(p)
|
||||||
|
#define Get32(p) GetUi32(p)
|
||||||
|
|
||||||
|
namespace NArchive {
|
||||||
|
namespace NArj {
|
||||||
|
|
||||||
|
const int kBlockSizeMin = 30;
|
||||||
|
const int kBlockSizeMax = 2600;
|
||||||
|
|
||||||
|
namespace NSignature
|
||||||
|
{
|
||||||
|
const Byte kSig0 = 0x60;
|
||||||
|
const Byte kSig1 = 0xEA;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace NFileHeader
|
||||||
|
{
|
||||||
|
namespace NCompressionMethod
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kStored = 0,
|
||||||
|
kCompressed1a = 1,
|
||||||
|
kCompressed1b = 2,
|
||||||
|
kCompressed1c = 3,
|
||||||
|
kCompressed2 = 4,
|
||||||
|
kNoDataNoCRC = 8,
|
||||||
|
kNoData = 9
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace NFileType
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kBinary = 0,
|
||||||
|
k7BitText = 1,
|
||||||
|
kArchiveHeader = 2,
|
||||||
|
kDirectory = 3,
|
||||||
|
kVolumeLablel = 4,
|
||||||
|
kChapterLabel = 5
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace NFlags
|
||||||
|
{
|
||||||
|
const Byte kGarbled = 1;
|
||||||
|
const Byte kVolume = 4;
|
||||||
|
const Byte kExtFile = 8;
|
||||||
|
const Byte kPathSym = 0x10;
|
||||||
|
const Byte kBackup = 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace NHostOS
|
||||||
|
{
|
||||||
|
enum EEnum
|
||||||
|
{
|
||||||
|
kMSDOS = 0, // filesystem used by MS-DOS, OS/2, Win32
|
||||||
|
// pkarj 2.50 (FAT / VFAT / FAT32 file systems)
|
||||||
|
kPRIMOS,
|
||||||
|
kUnix,
|
||||||
|
kAMIGA,
|
||||||
|
kMac,
|
||||||
|
kOS_2,
|
||||||
|
kAPPLE_GS,
|
||||||
|
kAtari_ST,
|
||||||
|
kNext,
|
||||||
|
kVAX_VMS,
|
||||||
|
kWIN95
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CArchiveHeader
|
||||||
|
{
|
||||||
|
// Byte ArchiverVersion;
|
||||||
|
// Byte ExtractVersion;
|
||||||
|
Byte HostOS;
|
||||||
|
// Byte Flags;
|
||||||
|
// Byte SecuryVersion;
|
||||||
|
// Byte FileType;
|
||||||
|
// Byte Reserved;
|
||||||
|
UInt32 CTime;
|
||||||
|
UInt32 MTime;
|
||||||
|
UInt32 ArchiveSize;
|
||||||
|
// UInt32 SecurityEnvelopeFilePosition;
|
||||||
|
// UInt16 FilespecPositionInFilename;
|
||||||
|
// UInt16 LengthOfSecurityEnvelopeSata;
|
||||||
|
// Byte EncryptionVersion;
|
||||||
|
// Byte LastChapter;
|
||||||
|
AString Name;
|
||||||
|
AString Comment;
|
||||||
|
|
||||||
|
HRESULT Parse(const Byte *p, unsigned size);
|
||||||
|
};
|
||||||
|
|
||||||
|
static HRESULT ReadString(const Byte *p, unsigned &size, AString &res)
|
||||||
|
{
|
||||||
|
AString s;
|
||||||
|
for (unsigned i = 0; i < size;)
|
||||||
|
{
|
||||||
|
char c = (char)p[i++];
|
||||||
|
if (c == 0)
|
||||||
|
{
|
||||||
|
size = i;
|
||||||
|
res = s;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
s += c;
|
||||||
|
}
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CArchiveHeader::Parse(const Byte *p, unsigned size)
|
||||||
|
{
|
||||||
|
if (size < kBlockSizeMin)
|
||||||
|
return S_FALSE;
|
||||||
|
Byte firstHeaderSize = p[0];
|
||||||
|
if (firstHeaderSize > size)
|
||||||
|
return S_FALSE;
|
||||||
|
// ArchiverVersion = p[1];
|
||||||
|
// ExtractVersion = p[2];
|
||||||
|
HostOS = p[3];
|
||||||
|
// Flags = p[4];
|
||||||
|
// SecuryVersion = p[5];
|
||||||
|
if (p[6] != NFileHeader::NFileType::kArchiveHeader)
|
||||||
|
return S_FALSE;
|
||||||
|
// Reserved = p[7];
|
||||||
|
CTime = Get32(p + 8);
|
||||||
|
MTime = Get32(p + 12);
|
||||||
|
ArchiveSize = Get32(p + 16);
|
||||||
|
// SecurityEnvelopeFilePosition = Get32(p + 20);
|
||||||
|
// UInt16 filespecPositionInFilename = Get16(p + 24);
|
||||||
|
// LengthOfSecurityEnvelopeSata = Get16(p + 26);
|
||||||
|
// EncryptionVersion = p[28];
|
||||||
|
// LastChapter = p[29];
|
||||||
|
unsigned pos = firstHeaderSize;
|
||||||
|
unsigned size1 = size - pos;
|
||||||
|
RINOK(ReadString(p + pos, size1, Name));
|
||||||
|
pos += size1;
|
||||||
|
size1 = size - pos;
|
||||||
|
RINOK(ReadString(p + pos, size1, Comment));
|
||||||
|
pos += size1;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CItem
|
||||||
|
{
|
||||||
|
AString Name;
|
||||||
|
AString Comment;
|
||||||
|
|
||||||
|
UInt32 MTime;
|
||||||
|
UInt32 PackSize;
|
||||||
|
UInt32 Size;
|
||||||
|
UInt32 FileCRC;
|
||||||
|
|
||||||
|
Byte Version;
|
||||||
|
Byte ExtractVersion;
|
||||||
|
Byte HostOS;
|
||||||
|
Byte Flags;
|
||||||
|
Byte Method;
|
||||||
|
Byte FileType;
|
||||||
|
|
||||||
|
// UInt16 FilespecPositionInFilename;
|
||||||
|
UInt16 FileAccessMode;
|
||||||
|
// Byte FirstChapter;
|
||||||
|
// Byte LastChapter;
|
||||||
|
|
||||||
|
UInt64 DataPosition;
|
||||||
|
|
||||||
|
bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kGarbled) != 0; }
|
||||||
|
bool IsDir() const { return (FileType == NFileHeader::NFileType::kDirectory); }
|
||||||
|
UInt32 GetWinAttributes() const
|
||||||
|
{
|
||||||
|
UInt32 winAtrributes;
|
||||||
|
switch(HostOS)
|
||||||
|
{
|
||||||
|
case NFileHeader::NHostOS::kMSDOS:
|
||||||
|
case NFileHeader::NHostOS::kWIN95:
|
||||||
|
winAtrributes = FileAccessMode;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
winAtrributes = 0;
|
||||||
|
}
|
||||||
|
if (IsDir())
|
||||||
|
winAtrributes |= FILE_ATTRIBUTE_DIRECTORY;
|
||||||
|
return winAtrributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT Parse(const Byte *p, unsigned size);
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT CItem::Parse(const Byte *p, unsigned size)
|
||||||
|
{
|
||||||
|
if (size < kBlockSizeMin)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
Byte firstHeaderSize = p[0];
|
||||||
|
|
||||||
|
Version = p[1];
|
||||||
|
ExtractVersion = p[2];
|
||||||
|
HostOS = p[3];
|
||||||
|
Flags = p[4];
|
||||||
|
Method = p[5];
|
||||||
|
FileType = p[6];
|
||||||
|
// Reserved = p[7];
|
||||||
|
MTime = Get32(p + 8);
|
||||||
|
PackSize = Get32(p + 12);
|
||||||
|
Size = Get32(p + 16);
|
||||||
|
FileCRC = Get32(p + 20);
|
||||||
|
// FilespecPositionInFilename = Get16(p + 24);
|
||||||
|
FileAccessMode = Get16(p + 26);
|
||||||
|
// FirstChapter = p[28];
|
||||||
|
// FirstChapter = p[29];
|
||||||
|
|
||||||
|
unsigned pos = firstHeaderSize;
|
||||||
|
unsigned size1 = size - pos;
|
||||||
|
RINOK(ReadString(p + pos, size1, Name));
|
||||||
|
pos += size1;
|
||||||
|
size1 = size - pos;
|
||||||
|
RINOK(ReadString(p + pos, size1, Comment));
|
||||||
|
pos += size1;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CInArchiveException
|
||||||
|
{
|
||||||
|
enum CCauseType
|
||||||
|
{
|
||||||
|
kUnexpectedEndOfArchive = 0,
|
||||||
|
kCRCError,
|
||||||
|
kIncorrectArchive,
|
||||||
|
}
|
||||||
|
Cause;
|
||||||
|
CInArchiveException(CCauseType cause): Cause(cause) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
class CInArchive
|
||||||
|
{
|
||||||
|
UInt32 _blockSize;
|
||||||
|
Byte _block[kBlockSizeMax + 4];
|
||||||
|
|
||||||
|
HRESULT ReadBlock(bool &filled);
|
||||||
|
HRESULT ReadSignatureAndBlock(bool &filled);
|
||||||
|
HRESULT SkeepExtendedHeaders();
|
||||||
|
|
||||||
|
HRESULT SafeReadBytes(void *data, UInt32 size);
|
||||||
|
|
||||||
|
public:
|
||||||
|
CArchiveHeader Header;
|
||||||
|
|
||||||
|
IInStream *Stream;
|
||||||
|
IArchiveOpenCallback *Callback;
|
||||||
|
UInt64 NumFiles;
|
||||||
|
UInt64 NumBytes;
|
||||||
|
|
||||||
|
HRESULT Open(const UInt64 *searchHeaderSizeLimit);
|
||||||
|
HRESULT GetNextItem(bool &filled, CItem &item);
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline bool TestMarkerCandidate(const Byte *p, unsigned maxSize)
|
||||||
|
{
|
||||||
|
if (p[0] != NSignature::kSig0 || p[1] != NSignature::kSig1)
|
||||||
|
return false;
|
||||||
|
UInt32 blockSize = Get16(p + 2);
|
||||||
|
p += 4;
|
||||||
|
if (p[6] != NFileHeader::NFileType::kArchiveHeader ||
|
||||||
|
p[0] > blockSize ||
|
||||||
|
maxSize < 2 + 2 + blockSize + 4 ||
|
||||||
|
blockSize < kBlockSizeMin || blockSize > kBlockSizeMax ||
|
||||||
|
p[28] > 8) // EncryptionVersion
|
||||||
|
return false;
|
||||||
|
// return (Get32(p + blockSize) == CrcCalc(p, blockSize));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT FindAndReadMarker(ISequentialInStream *stream, const UInt64 *searchHeaderSizeLimit, UInt64 &position)
|
||||||
|
{
|
||||||
|
position = 0;
|
||||||
|
|
||||||
|
const int kMarkerSizeMin = 2 + 2 + kBlockSizeMin + 4;
|
||||||
|
const int kMarkerSizeMax = 2 + 2 + kBlockSizeMax + 4;
|
||||||
|
|
||||||
|
CByteBuffer byteBuffer;
|
||||||
|
const UInt32 kBufSize = 1 << 16;
|
||||||
|
byteBuffer.SetCapacity(kBufSize);
|
||||||
|
Byte *buf = byteBuffer;
|
||||||
|
|
||||||
|
size_t processedSize = kMarkerSizeMax;
|
||||||
|
RINOK(ReadStream(stream, buf, &processedSize));
|
||||||
|
if (processedSize < kMarkerSizeMin)
|
||||||
|
return S_FALSE;
|
||||||
|
if (TestMarkerCandidate(buf, (unsigned)processedSize))
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
UInt32 numBytesPrev = (UInt32)processedSize - 1;
|
||||||
|
memmove(buf, buf + 1, numBytesPrev);
|
||||||
|
UInt64 curTestPos = 1;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (searchHeaderSizeLimit != NULL)
|
||||||
|
if (curTestPos > *searchHeaderSizeLimit)
|
||||||
|
return S_FALSE;
|
||||||
|
processedSize = kBufSize - numBytesPrev;
|
||||||
|
RINOK(ReadStream(stream, buf + numBytesPrev, &processedSize));
|
||||||
|
UInt32 numBytesInBuffer = numBytesPrev + (UInt32)processedSize;
|
||||||
|
if (numBytesInBuffer < kMarkerSizeMin)
|
||||||
|
return S_FALSE;
|
||||||
|
UInt32 numTests = numBytesInBuffer - kMarkerSizeMin + 1;
|
||||||
|
UInt32 pos;
|
||||||
|
for (pos = 0; pos < numTests; pos++)
|
||||||
|
{
|
||||||
|
for (; buf[pos] != NSignature::kSig0 && pos < numTests; pos++);
|
||||||
|
if (pos == numTests)
|
||||||
|
break;
|
||||||
|
if (TestMarkerCandidate(buf + pos, numBytesInBuffer - pos))
|
||||||
|
{
|
||||||
|
position = curTestPos + pos;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
curTestPos += pos;
|
||||||
|
numBytesPrev = numBytesInBuffer - numTests;
|
||||||
|
memmove(buf, buf + numTests, numBytesPrev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CInArchive::SafeReadBytes(void *data, UInt32 size)
|
||||||
|
{
|
||||||
|
size_t processed = size;
|
||||||
|
RINOK(ReadStream(Stream, data, &processed));
|
||||||
|
if (processed != size)
|
||||||
|
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CInArchive::ReadBlock(bool &filled)
|
||||||
|
{
|
||||||
|
filled = false;
|
||||||
|
Byte buf[2];
|
||||||
|
RINOK(SafeReadBytes(buf, 2));
|
||||||
|
_blockSize = Get16(buf);
|
||||||
|
if (_blockSize == 0)
|
||||||
|
return S_OK;
|
||||||
|
if (_blockSize > kBlockSizeMax)
|
||||||
|
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
|
||||||
|
RINOK(SafeReadBytes(_block, _blockSize + 4));
|
||||||
|
NumBytes += _blockSize + 6;
|
||||||
|
if (Get32(_block + _blockSize) != CrcCalc(_block, _blockSize))
|
||||||
|
throw CInArchiveException(CInArchiveException::kCRCError);
|
||||||
|
filled = true;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CInArchive::ReadSignatureAndBlock(bool &filled)
|
||||||
|
{
|
||||||
|
Byte id[2];
|
||||||
|
RINOK(SafeReadBytes(id, 2));
|
||||||
|
if (id[0] != NSignature::kSig0 || id[1] != NSignature::kSig1)
|
||||||
|
throw CInArchiveException(CInArchiveException::kIncorrectArchive);
|
||||||
|
return ReadBlock(filled);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CInArchive::SkeepExtendedHeaders()
|
||||||
|
{
|
||||||
|
for (UInt32 i = 0;; i++)
|
||||||
|
{
|
||||||
|
bool filled;
|
||||||
|
RINOK(ReadBlock(filled));
|
||||||
|
if (!filled)
|
||||||
|
return S_OK;
|
||||||
|
if (Callback && (i & 0xFF) == 0)
|
||||||
|
RINOK(Callback->SetCompleted(&NumFiles, &NumBytes));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CInArchive::Open(const UInt64 *searchHeaderSizeLimit)
|
||||||
|
{
|
||||||
|
UInt64 position = 0;
|
||||||
|
RINOK(FindAndReadMarker(Stream, searchHeaderSizeLimit, position));
|
||||||
|
RINOK(Stream->Seek(position, STREAM_SEEK_SET, NULL));
|
||||||
|
bool filled;
|
||||||
|
RINOK(ReadSignatureAndBlock(filled));
|
||||||
|
if (!filled)
|
||||||
|
return S_FALSE;
|
||||||
|
RINOK(Header.Parse(_block, _blockSize));
|
||||||
|
return SkeepExtendedHeaders();
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CInArchive::GetNextItem(bool &filled, CItem &item)
|
||||||
|
{
|
||||||
|
RINOK(ReadSignatureAndBlock(filled));
|
||||||
|
if (!filled)
|
||||||
|
return S_OK;
|
||||||
|
filled = false;
|
||||||
|
RINOK(item.Parse(_block, _blockSize));
|
||||||
|
/*
|
||||||
|
UInt32 extraData;
|
||||||
|
if ((header.Flags & NFileHeader::NFlags::kExtFile) != 0)
|
||||||
|
extraData = GetUInt32FromMemLE(_block + pos);
|
||||||
|
*/
|
||||||
|
|
||||||
|
RINOK(SkeepExtendedHeaders());
|
||||||
|
filled = true;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CHandler:
|
||||||
|
public IInArchive,
|
||||||
|
public CMyUnknownImp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MY_UNKNOWN_IMP1(IInArchive)
|
||||||
|
|
||||||
|
INTERFACE_IInArchive(;)
|
||||||
|
|
||||||
|
HRESULT Open2(IInStream *inStream, const UInt64 *maxCheckStartPosition,
|
||||||
|
IArchiveOpenCallback *callback);
|
||||||
|
private:
|
||||||
|
CInArchive _archive;
|
||||||
|
CObjectVector<CItem> _items;
|
||||||
|
CMyComPtr<IInStream> _stream;
|
||||||
|
};
|
||||||
|
|
||||||
|
const wchar_t *kHostOS[] =
|
||||||
|
{
|
||||||
|
L"MSDOS",
|
||||||
|
L"PRIMOS",
|
||||||
|
L"UNIX",
|
||||||
|
L"AMIGA",
|
||||||
|
L"MAC",
|
||||||
|
L"OS/2",
|
||||||
|
L"APPLE GS",
|
||||||
|
L"ATARI ST",
|
||||||
|
L"NEXT",
|
||||||
|
L"VAX VMS",
|
||||||
|
L"WIN95"
|
||||||
|
};
|
||||||
|
|
||||||
|
const wchar_t *kUnknownOS = L"Unknown";
|
||||||
|
|
||||||
|
const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
|
||||||
|
|
||||||
|
STATPROPSTG kArcProps[] =
|
||||||
|
{
|
||||||
|
{ NULL, kpidName, VT_BSTR},
|
||||||
|
{ NULL, kpidCTime, VT_BSTR},
|
||||||
|
{ NULL, kpidMTime, VT_BSTR},
|
||||||
|
{ NULL, kpidHostOS, VT_BSTR},
|
||||||
|
{ NULL, kpidComment, VT_BSTR}
|
||||||
|
};
|
||||||
|
|
||||||
|
STATPROPSTG kProps[] =
|
||||||
|
{
|
||||||
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
|
{ NULL, kpidIsDir, VT_BOOL},
|
||||||
|
{ NULL, kpidSize, VT_UI8},
|
||||||
|
{ NULL, kpidPackSize, VT_UI8},
|
||||||
|
{ NULL, kpidMTime, VT_FILETIME},
|
||||||
|
{ NULL, kpidAttrib, VT_UI4},
|
||||||
|
{ NULL, kpidEncrypted, VT_BOOL},
|
||||||
|
{ NULL, kpidCRC, VT_UI4},
|
||||||
|
{ NULL, kpidMethod, VT_UI1},
|
||||||
|
{ NULL, kpidHostOS, VT_BSTR},
|
||||||
|
{ NULL, kpidComment, VT_BSTR}
|
||||||
|
};
|
||||||
|
|
||||||
|
IMP_IInArchive_Props
|
||||||
|
IMP_IInArchive_ArcProps
|
||||||
|
|
||||||
|
static void SetTime(UInt32 dosTime, NWindows::NCOM::CPropVariant &prop)
|
||||||
|
{
|
||||||
|
if (dosTime == 0)
|
||||||
|
return;
|
||||||
|
FILETIME localFileTime, utc;
|
||||||
|
if (NTime::DosTimeToFileTime(dosTime, localFileTime))
|
||||||
|
{
|
||||||
|
if (!LocalFileTimeToFileTime(&localFileTime, &utc))
|
||||||
|
utc.dwHighDateTime = utc.dwLowDateTime = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
utc.dwHighDateTime = utc.dwLowDateTime = 0;
|
||||||
|
prop = utc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetHostOS(Byte hostOS, NWindows::NCOM::CPropVariant &prop)
|
||||||
|
{
|
||||||
|
prop = hostOS < kNumHostOSes ? kHostOS[hostOS] : kUnknownOS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetUnicodeString(const AString &s, NWindows::NCOM::CPropVariant &prop)
|
||||||
|
{
|
||||||
|
if (!s.IsEmpty())
|
||||||
|
prop = MultiByteToUnicodeString(s, CP_OEMCP);
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
NWindows::NCOM::CPropVariant prop;
|
||||||
|
switch(propID)
|
||||||
|
{
|
||||||
|
case kpidName: SetUnicodeString(_archive.Header.Name, prop); break;
|
||||||
|
case kpidCTime: SetTime(_archive.Header.CTime, prop); break;
|
||||||
|
case kpidMTime: SetTime(_archive.Header.MTime, prop); break;
|
||||||
|
case kpidHostOS: SetHostOS(_archive.Header.HostOS, prop); break;
|
||||||
|
case kpidComment: SetUnicodeString(_archive.Header.Comment, prop); break;
|
||||||
|
}
|
||||||
|
prop.Detach(value);
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||||
|
{
|
||||||
|
*numItems = _items.Size();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
NWindows::NCOM::CPropVariant prop;
|
||||||
|
const CItem &item = _items[index];
|
||||||
|
switch(propID)
|
||||||
|
{
|
||||||
|
case kpidPath: prop = NItemName::GetOSName(MultiByteToUnicodeString(item.Name, CP_OEMCP)); break;
|
||||||
|
case kpidIsDir: prop = item.IsDir(); break;
|
||||||
|
case kpidSize: prop = item.Size; break;
|
||||||
|
case kpidPackSize: prop = item.PackSize; break;
|
||||||
|
case kpidAttrib: prop = item.GetWinAttributes(); break;
|
||||||
|
case kpidEncrypted: prop = item.IsEncrypted(); break;
|
||||||
|
case kpidCRC: prop = item.FileCRC; break;
|
||||||
|
case kpidMethod: prop = item.Method; break;
|
||||||
|
case kpidHostOS: SetHostOS(item.HostOS, prop); break;
|
||||||
|
case kpidMTime: SetTime(item.MTime, prop); break;
|
||||||
|
case kpidComment: SetUnicodeString(item.Comment, prop); break;
|
||||||
|
}
|
||||||
|
prop.Detach(value);
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CHandler::Open2(IInStream *inStream, const UInt64 *maxCheckStartPosition,
|
||||||
|
IArchiveOpenCallback *callback)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
|
||||||
|
UInt64 endPos = 0;
|
||||||
|
if (callback != NULL)
|
||||||
|
{
|
||||||
|
RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos));
|
||||||
|
RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
_archive.Stream = inStream;
|
||||||
|
_archive.Callback = callback;
|
||||||
|
_archive.NumFiles = _archive.NumBytes = 0;
|
||||||
|
|
||||||
|
RINOK(_archive.Open(maxCheckStartPosition));
|
||||||
|
if (callback != NULL)
|
||||||
|
RINOK(callback->SetTotal(NULL, &endPos));
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
CItem item;
|
||||||
|
bool filled;
|
||||||
|
|
||||||
|
|
||||||
|
RINOK(_archive.GetNextItem(filled, item));
|
||||||
|
|
||||||
|
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &item.DataPosition));
|
||||||
|
|
||||||
|
if (!filled)
|
||||||
|
break;
|
||||||
|
_items.Add(item);
|
||||||
|
|
||||||
|
if (inStream->Seek(item.PackSize, STREAM_SEEK_CUR, NULL) != S_OK)
|
||||||
|
throw CInArchiveException(CInArchiveException::kUnexpectedEndOfArchive);
|
||||||
|
|
||||||
|
_archive.NumFiles = _items.Size();
|
||||||
|
_archive.NumBytes = item.DataPosition;
|
||||||
|
|
||||||
|
if (callback != NULL && _items.Size() % 100 == 0)
|
||||||
|
{
|
||||||
|
RINOK(callback->SetCompleted(&_archive.NumFiles, &_archive.NumBytes));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||||
|
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
HRESULT res;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
res = Open2(inStream, maxCheckStartPosition, callback);
|
||||||
|
if (res == S_OK)
|
||||||
|
{
|
||||||
|
_stream = inStream;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(const CInArchiveException &) { res = S_FALSE; }
|
||||||
|
Close();
|
||||||
|
return res;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Close()
|
||||||
|
{
|
||||||
|
_items.Clear();
|
||||||
|
_stream.Release();
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||||
|
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
||||||
|
{
|
||||||
|
COM_TRY_BEGIN
|
||||||
|
bool testMode = (testModeSpec != 0);
|
||||||
|
UInt64 totalUnpacked = 0, totalPacked = 0;
|
||||||
|
bool allFilesMode = (numItems == UInt32(-1));
|
||||||
|
if (allFilesMode)
|
||||||
|
numItems = _items.Size();
|
||||||
|
if (numItems == 0)
|
||||||
|
return S_OK;
|
||||||
|
UInt32 i;
|
||||||
|
for (i = 0; i < numItems; i++)
|
||||||
|
{
|
||||||
|
const CItem &item = _items[allFilesMode ? i : indices[i]];
|
||||||
|
totalUnpacked += item.Size;
|
||||||
|
totalPacked += item.PackSize;
|
||||||
|
}
|
||||||
|
extractCallback->SetTotal(totalUnpacked);
|
||||||
|
|
||||||
|
totalUnpacked = totalPacked = 0;
|
||||||
|
UInt64 curUnpacked, curPacked;
|
||||||
|
|
||||||
|
CMyComPtr<ICompressCoder> arj1Decoder;
|
||||||
|
CMyComPtr<ICompressCoder> arj2Decoder;
|
||||||
|
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
||||||
|
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||||
|
|
||||||
|
CLocalProgress *lps = new CLocalProgress;
|
||||||
|
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||||
|
lps->Init(extractCallback, false);
|
||||||
|
|
||||||
|
CLimitedSequentialInStream *inStreamSpec = new CLimitedSequentialInStream;
|
||||||
|
CMyComPtr<ISequentialInStream> inStream(inStreamSpec);
|
||||||
|
inStreamSpec->SetStream(_stream);
|
||||||
|
|
||||||
|
for (i = 0; i < numItems; i++, totalUnpacked += curUnpacked, totalPacked += curPacked)
|
||||||
|
{
|
||||||
|
lps->InSize = totalPacked;
|
||||||
|
lps->OutSize = totalUnpacked;
|
||||||
|
RINOK(lps->SetCur());
|
||||||
|
|
||||||
|
curUnpacked = curPacked = 0;
|
||||||
|
|
||||||
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
|
Int32 askMode = testMode ?
|
||||||
|
NExtract::NAskMode::kTest :
|
||||||
|
NExtract::NAskMode::kExtract;
|
||||||
|
Int32 index = allFilesMode ? i : indices[i];
|
||||||
|
const CItem &item = _items[index];
|
||||||
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
|
|
||||||
|
if (item.IsDir())
|
||||||
|
{
|
||||||
|
// if (!testMode)
|
||||||
|
{
|
||||||
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!testMode && (!realOutStream))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
RINOK(extractCallback->PrepareOperation(askMode));
|
||||||
|
curUnpacked = item.Size;
|
||||||
|
curPacked = item.PackSize;
|
||||||
|
|
||||||
|
{
|
||||||
|
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
|
||||||
|
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||||
|
outStreamSpec->SetStream(realOutStream);
|
||||||
|
realOutStream.Release();
|
||||||
|
outStreamSpec->Init();
|
||||||
|
|
||||||
|
inStreamSpec->Init(item.PackSize);
|
||||||
|
|
||||||
|
UInt64 pos;
|
||||||
|
_stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos);
|
||||||
|
|
||||||
|
HRESULT result = S_OK;
|
||||||
|
Int32 opRes = NExtract::NOperationResult::kOK;
|
||||||
|
|
||||||
|
if (item.IsEncrypted())
|
||||||
|
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(item.Method)
|
||||||
|
{
|
||||||
|
case NFileHeader::NCompressionMethod::kStored:
|
||||||
|
{
|
||||||
|
result = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
|
||||||
|
if (result == S_OK && copyCoderSpec->TotalSize != item.PackSize)
|
||||||
|
result = S_FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NFileHeader::NCompressionMethod::kCompressed1a:
|
||||||
|
case NFileHeader::NCompressionMethod::kCompressed1b:
|
||||||
|
case NFileHeader::NCompressionMethod::kCompressed1c:
|
||||||
|
{
|
||||||
|
if (!arj1Decoder)
|
||||||
|
arj1Decoder = new NCompress::NArj::NDecoder1::CCoder;
|
||||||
|
result = arj1Decoder->Code(inStream, outStream, NULL, &curUnpacked, progress);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NFileHeader::NCompressionMethod::kCompressed2:
|
||||||
|
{
|
||||||
|
if (!arj2Decoder)
|
||||||
|
arj2Decoder = new NCompress::NArj::NDecoder2::CCoder;
|
||||||
|
result = arj2Decoder->Code(inStream, outStream, NULL, &curUnpacked, progress);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
opRes = NExtract::NOperationResult::kUnSupportedMethod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (opRes == NExtract::NOperationResult::kOK)
|
||||||
|
{
|
||||||
|
if (result == S_FALSE)
|
||||||
|
opRes = NExtract::NOperationResult::kDataError;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RINOK(result);
|
||||||
|
opRes = (outStreamSpec->GetCRC() == item.FileCRC) ?
|
||||||
|
NExtract::NOperationResult::kOK:
|
||||||
|
NExtract::NOperationResult::kCRCError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outStream.Release();
|
||||||
|
RINOK(extractCallback->SetOperationResult(opRes));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
COM_TRY_END
|
||||||
|
}
|
||||||
|
|
||||||
|
static IInArchive *CreateArc() { return new CHandler; }
|
||||||
|
|
||||||
|
static CArcInfo g_ArcInfo =
|
||||||
|
{ L"Arj", L"arj", 0, 4, { 0x60, 0xEA }, 2, false, CreateArc, 0 };
|
||||||
|
|
||||||
|
REGISTER_ARC(Arj)
|
||||||
|
|
||||||
|
}}
|
||||||
@@ -21,9 +21,9 @@ namespace NBZip2 {
|
|||||||
|
|
||||||
static const CMethodId kMethodId_BZip2 = 0x040202;
|
static const CMethodId kMethodId_BZip2 = 0x040202;
|
||||||
|
|
||||||
STATPROPSTG kProps[] =
|
STATPROPSTG kProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidPackedSize, VT_UI8}
|
{ NULL, kpidPackSize, VT_UI8}
|
||||||
};
|
};
|
||||||
|
|
||||||
IMP_IInArchive_Props
|
IMP_IInArchive_Props
|
||||||
@@ -40,13 +40,13 @@ STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIA
|
|||||||
NWindows::NCOM::CPropVariant prop;
|
NWindows::NCOM::CPropVariant prop;
|
||||||
switch(propID)
|
switch(propID)
|
||||||
{
|
{
|
||||||
case kpidPackedSize: prop = _item.PackSize; break;
|
case kpidPackSize: prop = _item.PackSize; break;
|
||||||
}
|
}
|
||||||
prop.Detach(value);
|
prop.Detach(value);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||||
const UInt64 * /* maxCheckStartPosition */,
|
const UInt64 * /* maxCheckStartPosition */,
|
||||||
IArchiveOpenCallback * /* openArchiveCallback */)
|
IArchiveOpenCallback * /* openArchiveCallback */)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NBZip2 {
|
namespace NBZip2 {
|
||||||
|
|
||||||
class CHandler:
|
class CHandler:
|
||||||
public IInArchive,
|
public IInArchive,
|
||||||
public IOutArchive,
|
public IOutArchive,
|
||||||
public ISetProperties,
|
public ISetProperties,
|
||||||
@@ -35,11 +35,11 @@ class CHandler:
|
|||||||
|
|
||||||
DECL_EXTERNAL_CODECS_VARS
|
DECL_EXTERNAL_CODECS_VARS
|
||||||
|
|
||||||
void InitMethodProperties()
|
void InitMethodProperties()
|
||||||
{
|
{
|
||||||
_level = 5;
|
_level = 5;
|
||||||
_dicSize =
|
_dicSize =
|
||||||
_numPasses = 0xFFFFFFFF;
|
_numPasses = 0xFFFFFFFF;
|
||||||
#ifdef COMPRESS_MT
|
#ifdef COMPRESS_MT
|
||||||
_numThreads = NWindows::NSystem::GetNumberOfProcessors();;
|
_numThreads = NWindows::NSystem::GetNumberOfProcessors();;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
NCOM::CPropVariant prop;
|
NCOM::CPropVariant prop;
|
||||||
RINOK(updateCallback->GetProperty(0, kpidIsFolder, &prop));
|
RINOK(updateCallback->GetProperty(0, kpidIsDir, &prop));
|
||||||
if (prop.vt == VT_BOOL)
|
if (prop.vt == VT_BOOL)
|
||||||
{
|
{
|
||||||
if (prop.boolVal != VARIANT_FALSE)
|
if (prop.boolVal != VARIANT_FALSE)
|
||||||
@@ -79,21 +79,21 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
|
|
||||||
UInt32 dicSize = _dicSize;
|
UInt32 dicSize = _dicSize;
|
||||||
if (dicSize == 0xFFFFFFFF)
|
if (dicSize == 0xFFFFFFFF)
|
||||||
dicSize = (_level >= 5 ? kDicSizeX5 :
|
dicSize = (_level >= 5 ? kDicSizeX5 :
|
||||||
(_level >= 3 ? kDicSizeX3 :
|
(_level >= 3 ? kDicSizeX3 :
|
||||||
kDicSizeX1));
|
kDicSizeX1));
|
||||||
|
|
||||||
UInt32 numPasses = _numPasses;
|
UInt32 numPasses = _numPasses;
|
||||||
if (numPasses == 0xFFFFFFFF)
|
if (numPasses == 0xFFFFFFFF)
|
||||||
numPasses = (_level >= 9 ? kNumPassesX9 :
|
numPasses = (_level >= 9 ? kNumPassesX9 :
|
||||||
(_level >= 7 ? kNumPassesX7 :
|
(_level >= 7 ? kNumPassesX7 :
|
||||||
kNumPassesX1));
|
kNumPassesX1));
|
||||||
|
|
||||||
return UpdateArchive(
|
return UpdateArchive(
|
||||||
EXTERNAL_CODECS_VARS
|
EXTERNAL_CODECS_VARS
|
||||||
size, outStream, 0, dicSize, numPasses,
|
size, outStream, 0, dicSize, numPasses,
|
||||||
#ifdef COMPRESS_MT
|
#ifdef COMPRESS_MT
|
||||||
_numThreads,
|
_numThreads,
|
||||||
#endif
|
#endif
|
||||||
updateCallback);
|
updateCallback);
|
||||||
}
|
}
|
||||||
@@ -151,6 +151,6 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
|||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -47,15 +47,15 @@ HRESULT UpdateArchive(
|
|||||||
encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
|
encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
|
||||||
if (setCoderProperties)
|
if (setCoderProperties)
|
||||||
{
|
{
|
||||||
NWindows::NCOM::CPropVariant properties[] =
|
NWindows::NCOM::CPropVariant properties[] =
|
||||||
{
|
{
|
||||||
dictionary,
|
dictionary,
|
||||||
numPasses
|
numPasses
|
||||||
#ifdef COMPRESS_MT
|
#ifdef COMPRESS_MT
|
||||||
, numThreads
|
, numThreads
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
PROPID propIDs[] =
|
PROPID propIDs[] =
|
||||||
{
|
{
|
||||||
NCoderPropID::kDictionarySize,
|
NCoderPropID::kDictionarySize,
|
||||||
NCoderPropID::kNumPasses
|
NCoderPropID::kNumPasses
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
// StdAfx.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "../../../../C/Alloc.h"
|
#include "../../../../C/Alloc.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ public:
|
|||||||
m_Value ^= ((UInt32)(m_Hist[i])) << (8 * (m_Pos - i - 1));
|
m_Value ^= ((UInt32)(m_Hist[i])) << (8 * (m_Pos - i - 1));
|
||||||
}
|
}
|
||||||
void UpdateUInt32(UInt32 v) { m_Value ^= v; }
|
void UpdateUInt32(UInt32 v) { m_Value ^= v; }
|
||||||
UInt32 GetResult() const { return m_Value; }
|
UInt32 GetResult() const { return m_Value; }
|
||||||
};
|
};
|
||||||
|
|
||||||
void CCheckSum2::Update(const void *data, UInt32 size)
|
void CCheckSum2::Update(const void *data, UInt32 size)
|
||||||
@@ -65,7 +65,7 @@ void CCheckSum2::Update(const void *data, UInt32 size)
|
|||||||
|
|
||||||
int numWords = size / 4;
|
int numWords = size / 4;
|
||||||
|
|
||||||
while (numWords-- != 0)
|
while (numWords-- != 0)
|
||||||
{
|
{
|
||||||
UInt32 temp = *dataPointer++;
|
UInt32 temp = *dataPointer++;
|
||||||
temp |= ((UInt32)(*dataPointer++)) << 8;
|
temp |= ((UInt32)(*dataPointer++)) << 8;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NCab {
|
namespace NCab {
|
||||||
|
|
||||||
class CCabBlockInStream:
|
class CCabBlockInStream:
|
||||||
public ISequentialInStream,
|
public ISequentialInStream,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,19 +31,18 @@ namespace NCab {
|
|||||||
// #define _CAB_DETAILS
|
// #define _CAB_DETAILS
|
||||||
|
|
||||||
#ifdef _CAB_DETAILS
|
#ifdef _CAB_DETAILS
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kpidBlockReal = kpidUserDefined
|
kpidBlockReal = kpidUserDefined
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
STATPROPSTG kProps[] =
|
STATPROPSTG kProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidPath, VT_BSTR},
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
// { NULL, kpidIsFolder, VT_BOOL},
|
|
||||||
{ NULL, kpidSize, VT_UI8},
|
{ NULL, kpidSize, VT_UI8},
|
||||||
{ NULL, kpidLastWriteTime, VT_FILETIME},
|
{ NULL, kpidMTime, VT_FILETIME},
|
||||||
{ NULL, kpidAttributes, VT_UI4},
|
{ NULL, kpidAttrib, VT_UI4},
|
||||||
{ NULL, kpidMethod, VT_BSTR},
|
{ NULL, kpidMethod, VT_BSTR},
|
||||||
{ NULL, kpidBlock, VT_I4}
|
{ NULL, kpidBlock, VT_I4}
|
||||||
#ifdef _CAB_DETAILS
|
#ifdef _CAB_DETAILS
|
||||||
@@ -54,7 +53,7 @@ STATPROPSTG kProps[] =
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static const wchar_t *kMethods[] =
|
static const wchar_t *kMethods[] =
|
||||||
{
|
{
|
||||||
L"None",
|
L"None",
|
||||||
L"MSZip",
|
L"MSZip",
|
||||||
@@ -65,7 +64,7 @@ static const wchar_t *kMethods[] =
|
|||||||
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 wchar_t *kUnknownMethod = L"Unknown";
|
||||||
|
|
||||||
STATPROPSTG kArcProps[] =
|
STATPROPSTG kArcProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidMethod, VT_BSTR},
|
{ NULL, kpidMethod, VT_BSTR},
|
||||||
// { NULL, kpidSolid, VT_BOOL},
|
// { NULL, kpidSolid, VT_BOOL},
|
||||||
@@ -101,7 +100,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
resString += L' ';
|
resString += L' ';
|
||||||
resString += method;
|
resString += method;
|
||||||
}
|
}
|
||||||
prop = resString;
|
prop = resString;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// case kpidSolid: prop = _database.IsSolid(); break;
|
// case kpidSolid: prop = _database.IsSolid(); break;
|
||||||
@@ -145,13 +144,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
prop = (const wchar_t *)NItemName::WinNameToOSName(unicodeName);
|
prop = (const wchar_t *)NItemName::WinNameToOSName(unicodeName);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kpidIsFolder:
|
case kpidIsDir: prop = item.IsDir(); break;
|
||||||
prop = item.IsDirectory();
|
case kpidSize: prop = item.Size; break;
|
||||||
break;
|
case kpidAttrib: prop = item.GetWinAttributes(); break;
|
||||||
case kpidSize:
|
|
||||||
prop = item.Size;
|
case kpidMTime:
|
||||||
break;
|
|
||||||
case kpidLastWriteTime:
|
|
||||||
{
|
{
|
||||||
FILETIME localFileTime, utcFileTime;
|
FILETIME localFileTime, utcFileTime;
|
||||||
if (NTime::DosTimeToFileTime(item.Time, localFileTime))
|
if (NTime::DosTimeToFileTime(item.Time, localFileTime))
|
||||||
@@ -164,9 +161,6 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
prop = utcFileTime;
|
prop = utcFileTime;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kpidAttributes:
|
|
||||||
prop = item.GetWinAttributes();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kpidMethod:
|
case kpidMethod:
|
||||||
{
|
{
|
||||||
@@ -174,7 +168,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
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;
|
UString 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 += L":";
|
||||||
@@ -185,21 +179,13 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
prop = method;
|
prop = method;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kpidBlock:
|
case kpidBlock: prop = (Int32)m_Database.GetFolderIndex(&mvItem); break;
|
||||||
prop = (Int32)m_Database.GetFolderIndex(&mvItem);
|
|
||||||
break;
|
|
||||||
|
|
||||||
#ifdef _CAB_DETAILS
|
#ifdef _CAB_DETAILS
|
||||||
|
|
||||||
case kpidBlockReal:
|
case kpidBlockReal: prop = (UInt32)item.FolderIndex; break;
|
||||||
prop = UInt32(item.FolderIndex);
|
case kpidOffset: prop = (UInt32)item.Offset; break;
|
||||||
break;
|
case kpidVolume: prop = (UInt32)mvItem.VolumeIndex; break;
|
||||||
case kpidOffset:
|
|
||||||
prop = (UInt32)item.Offset;
|
|
||||||
break;
|
|
||||||
case kpidVolume:
|
|
||||||
prop = (UInt32)mvItem.VolumeIndex;
|
|
||||||
break;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -209,7 +195,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
class CPropgressImp: public CProgressVirt
|
class CProgressImp: public CProgressVirt
|
||||||
{
|
{
|
||||||
CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback;
|
CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback;
|
||||||
public:
|
public:
|
||||||
@@ -219,14 +205,14 @@ public:
|
|||||||
{ m_OpenArchiveCallback = openArchiveCallback; }
|
{ m_OpenArchiveCallback = openArchiveCallback; }
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles)
|
STDMETHODIMP CProgressImp::SetTotal(const UInt64 *numFiles)
|
||||||
{
|
{
|
||||||
if (m_OpenArchiveCallback)
|
if (m_OpenArchiveCallback)
|
||||||
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
|
STDMETHODIMP CProgressImp::SetCompleted(const UInt64 *numFiles)
|
||||||
{
|
{
|
||||||
if (m_OpenArchiveCallback)
|
if (m_OpenArchiveCallback)
|
||||||
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
||||||
@@ -234,9 +220,9 @@ STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||||
const UInt64 *maxCheckStartPosition,
|
const UInt64 *maxCheckStartPosition,
|
||||||
IArchiveOpenCallback *openArchiveCallback)
|
IArchiveOpenCallback *callback)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
Close();
|
Close();
|
||||||
@@ -244,7 +230,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|||||||
CInArchive archive;
|
CInArchive archive;
|
||||||
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
|
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
|
||||||
{
|
{
|
||||||
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = openArchiveCallback;
|
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackWrap = callback;
|
||||||
openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
|
openArchiveCallbackWrap.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,7 +250,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|||||||
{
|
{
|
||||||
const CDatabaseEx &dbPrev = m_Database.Volumes[prevChecked ? m_Database.Volumes.Size() - 1 : 0];
|
const CDatabaseEx &dbPrev = m_Database.Volumes[prevChecked ? m_Database.Volumes.Size() - 1 : 0];
|
||||||
if (dbPrev.ArchiveInfo.SetID != db.ArchiveInfo.SetID ||
|
if (dbPrev.ArchiveInfo.SetID != db.ArchiveInfo.SetID ||
|
||||||
dbPrev.ArchiveInfo.CabinetNumber + (prevChecked ? 1: - 1) !=
|
dbPrev.ArchiveInfo.CabinetNumber + (prevChecked ? 1: - 1) !=
|
||||||
db.ArchiveInfo.CabinetNumber)
|
db.ArchiveInfo.CabinetNumber)
|
||||||
res = S_FALSE;
|
res = S_FALSE;
|
||||||
}
|
}
|
||||||
@@ -273,7 +259,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|||||||
m_Database.Volumes.Insert(prevChecked ? m_Database.Volumes.Size() : 0, db);
|
m_Database.Volumes.Insert(prevChecked ? m_Database.Volumes.Size() : 0, db);
|
||||||
else if (res != S_FALSE)
|
else if (res != S_FALSE)
|
||||||
return res;
|
return res;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_Database.Volumes.IsEmpty())
|
if (m_Database.Volumes.IsEmpty())
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
@@ -283,7 +269,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
|||||||
}
|
}
|
||||||
|
|
||||||
numItems += db.Items.Size();
|
numItems += db.Items.Size();
|
||||||
RINOK(openArchiveCallback->SetCompleted(&numItems, NULL));
|
RINOK(callback->SetCompleted(&numItems, NULL));
|
||||||
|
|
||||||
nextStream = 0;
|
nextStream = 0;
|
||||||
for (;;)
|
for (;;)
|
||||||
@@ -342,7 +328,7 @@ STDMETHODIMP CHandler::Close()
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CCabFolderOutStream:
|
class CCabFolderOutStream:
|
||||||
public ISequentialOutStream,
|
public ISequentialOutStream,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
@@ -373,8 +359,8 @@ public:
|
|||||||
|
|
||||||
void Init(
|
void Init(
|
||||||
const CMvDatabaseEx *database,
|
const CMvDatabaseEx *database,
|
||||||
const CRecordVector<bool> *extractStatuses,
|
const CRecordVector<bool> *extractStatuses,
|
||||||
int startIndex,
|
int startIndex,
|
||||||
UInt64 folderSize,
|
UInt64 folderSize,
|
||||||
IArchiveExtractCallback *extractCallback,
|
IArchiveExtractCallback *extractCallback,
|
||||||
bool testMode);
|
bool testMode);
|
||||||
@@ -387,8 +373,8 @@ public:
|
|||||||
|
|
||||||
void CCabFolderOutStream::Init(
|
void CCabFolderOutStream::Init(
|
||||||
const CMvDatabaseEx *database,
|
const CMvDatabaseEx *database,
|
||||||
const CRecordVector<bool> *extractStatuses,
|
const CRecordVector<bool> *extractStatuses,
|
||||||
int startIndex,
|
int startIndex,
|
||||||
UInt64 folderSize,
|
UInt64 folderSize,
|
||||||
IArchiveExtractCallback *extractCallback,
|
IArchiveExtractCallback *extractCallback,
|
||||||
bool testMode)
|
bool testMode)
|
||||||
@@ -409,7 +395,7 @@ void CCabFolderOutStream::Init(
|
|||||||
|
|
||||||
HRESULT CCabFolderOutStream::OpenFile()
|
HRESULT CCabFolderOutStream::OpenFile()
|
||||||
{
|
{
|
||||||
Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ?
|
Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ?
|
||||||
NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NExtract::NAskMode::kExtract) :
|
NExtract::NAskMode::kExtract) :
|
||||||
NExtract::NAskMode::kSkip;
|
NExtract::NAskMode::kSkip;
|
||||||
@@ -474,7 +460,7 @@ HRESULT CCabFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
|||||||
{
|
{
|
||||||
m_RealOutStream.Release();
|
m_RealOutStream.Release();
|
||||||
RINOK(m_ExtractCallback->SetOperationResult(
|
RINOK(m_ExtractCallback->SetOperationResult(
|
||||||
m_IsOk ?
|
m_IsOk ?
|
||||||
NArchive::NExtract::NOperationResult::kOK:
|
NArchive::NExtract::NOperationResult::kOK:
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
NArchive::NExtract::NOperationResult::kDataError));
|
||||||
m_FileIsOpen = false;
|
m_FileIsOpen = false;
|
||||||
@@ -574,7 +560,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
int index = allFilesMode ? i : indices[i];
|
int index = allFilesMode ? i : indices[i];
|
||||||
const CMvItem &mvItem = m_Database.Items[index];
|
const CMvItem &mvItem = m_Database.Items[index];
|
||||||
const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||||
if (item.IsDirectory())
|
if (item.IsDir())
|
||||||
continue;
|
continue;
|
||||||
int folderIndex = m_Database.GetFolderIndex(&mvItem);
|
int folderIndex = m_Database.GetFolderIndex(&mvItem);
|
||||||
if (folderIndex != lastFolder)
|
if (folderIndex != lastFolder)
|
||||||
@@ -622,9 +608,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
const CItem &item = db.Items[itemIndex];
|
const CItem &item = db.Items[itemIndex];
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
if (item.IsDirectory())
|
if (item.IsDir())
|
||||||
{
|
{
|
||||||
Int32 askMode= testMode ?
|
Int32 askMode= testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NArchive::NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NArchive::NExtract::NAskMode::kExtract;
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
@@ -638,7 +624,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
if (folderIndex < 0)
|
if (folderIndex < 0)
|
||||||
{
|
{
|
||||||
// If we need previous archive
|
// If we need previous archive
|
||||||
Int32 askMode= testMode ?
|
Int32 askMode= testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NArchive::NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NArchive::NExtract::NAskMode::kExtract;
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
@@ -661,7 +647,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
int indexNext = allFilesMode ? i : indices[i];
|
int indexNext = allFilesMode ? i : indices[i];
|
||||||
const CMvItem &mvItem = m_Database.Items[indexNext];
|
const CMvItem &mvItem = m_Database.Items[indexNext];
|
||||||
const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||||
if (item.IsDirectory())
|
if (item.IsDir())
|
||||||
continue;
|
continue;
|
||||||
int newFolderIndex = m_Database.GetFolderIndex(&mvItem);
|
int newFolderIndex = m_Database.GetFolderIndex(&mvItem);
|
||||||
|
|
||||||
@@ -683,7 +669,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
|
|
||||||
const CFolder &folder = db.Folders[item.GetFolderIndex(db.Folders.Size())];
|
const CFolder &folder = db.Folders[item.GetFolderIndex(db.Folders.Size())];
|
||||||
|
|
||||||
cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2,
|
cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2,
|
||||||
curUnpack, extractCallback, testMode);
|
curUnpack, extractCallback, testMode);
|
||||||
|
|
||||||
cabBlockInStreamSpec->MsZip = false;
|
cabBlockInStreamSpec->MsZip = false;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NCab {
|
namespace NCab {
|
||||||
|
|
||||||
class CHandler:
|
class CHandler:
|
||||||
public IInArchive,
|
public IInArchive,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,12 +8,8 @@ namespace NArchive{
|
|||||||
namespace NCab{
|
namespace NCab{
|
||||||
namespace NHeader{
|
namespace NHeader{
|
||||||
|
|
||||||
namespace NArchive {
|
Byte kMarker[kMarkerSize] = {'M' + 1, 'S', 'C', 'F', 0, 0, 0, 0 };
|
||||||
|
|
||||||
UInt32 kSignature = 0x4643534d + 1;
|
struct SignatureInitializer { SignatureInitializer() { kMarker[0]--; }; } g_SignatureInitializer;
|
||||||
static class CSignatureInitializer
|
|
||||||
{ public: CSignatureInitializer() { kSignature--; }} g_SignatureInitializer;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
|||||||
@@ -7,11 +7,13 @@
|
|||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace NCab {
|
namespace NCab {
|
||||||
namespace NHeader{
|
namespace NHeader {
|
||||||
|
|
||||||
namespace NArchive
|
const unsigned kMarkerSize = 8;
|
||||||
|
extern Byte kMarker[kMarkerSize];
|
||||||
|
|
||||||
|
namespace NArchive
|
||||||
{
|
{
|
||||||
extern UInt32 kSignature;
|
|
||||||
namespace NFlags
|
namespace NFlags
|
||||||
{
|
{
|
||||||
const int kPrevCabinet = 0x0001;
|
const int kPrevCabinet = 0x0001;
|
||||||
|
|||||||
@@ -2,15 +2,12 @@
|
|||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "Common/StringConvert.h"
|
|
||||||
#include "Common/MyCom.h"
|
|
||||||
#include "CabIn.h"
|
#include "CabIn.h"
|
||||||
#include "Windows/Defs.h"
|
|
||||||
|
|
||||||
#include "../../Common/StreamUtils.h"
|
#include "../Common/FindSignature.h"
|
||||||
|
|
||||||
namespace NArchive{
|
namespace NArchive {
|
||||||
namespace NCab{
|
namespace NCab {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size)
|
static HRESULT ReadBytes(IInStream *inStream, void *data, UInt32 size)
|
||||||
@@ -94,39 +91,21 @@ void CInArchive::Skeep(size_t size)
|
|||||||
ReadByte();
|
ReadByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CInArchive::Open2(IInStream *inStream,
|
HRESULT CInArchive::Open2(IInStream *stream,
|
||||||
const UInt64 *searchHeaderSizeLimit,
|
const UInt64 *searchHeaderSizeLimit,
|
||||||
CDatabase &database)
|
CDatabase &database)
|
||||||
{
|
{
|
||||||
database.Clear();
|
database.Clear();
|
||||||
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &database.StartPosition));
|
RINOK(stream->Seek(0, STREAM_SEEK_SET, &database.StartPosition));
|
||||||
|
|
||||||
{
|
RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize,
|
||||||
if (!inBuffer.Create(1 << 17))
|
searchHeaderSizeLimit, database.StartPosition));
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
inBuffer.SetStream(inStream);
|
RINOK(stream->Seek(database.StartPosition + NHeader::kMarkerSize, STREAM_SEEK_SET, NULL));
|
||||||
inBuffer.Init();
|
if (!inBuffer.Create(1 << 17))
|
||||||
UInt64 value = 0;
|
return E_OUTOFMEMORY;
|
||||||
const int kSignatureSize = 8;
|
inBuffer.SetStream(stream);
|
||||||
UInt64 kSignature64 = NHeader::NArchive::kSignature;
|
inBuffer.Init();
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
Byte b;
|
|
||||||
if (!inBuffer.ReadByte(b))
|
|
||||||
return S_FALSE;
|
|
||||||
value >>= 8;
|
|
||||||
value |= ((UInt64)b) << ((kSignatureSize - 1) * 8);
|
|
||||||
if (inBuffer.GetProcessedSize() >= kSignatureSize)
|
|
||||||
{
|
|
||||||
if (value == kSignature64)
|
|
||||||
break;
|
|
||||||
if (searchHeaderSizeLimit != NULL)
|
|
||||||
if (inBuffer.GetProcessedSize() > (*searchHeaderSizeLimit))
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
database.StartPosition += inBuffer.GetProcessedSize() - kSignatureSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
CInArchiveInfo &archiveInfo = database.ArchiveInfo;
|
CInArchiveInfo &archiveInfo = database.ArchiveInfo;
|
||||||
|
|
||||||
@@ -141,7 +120,9 @@ HRESULT CInArchive::Open2(IInStream *inStream,
|
|||||||
archiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major
|
archiveInfo.VersionMajor = ReadByte(); // cabinet file format version, major
|
||||||
archiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet
|
archiveInfo.NumFolders = ReadUInt16(); // number of CFFOLDER entries in this cabinet
|
||||||
archiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet
|
archiveInfo.NumFiles = ReadUInt16(); // number of CFFILE entries in this cabinet
|
||||||
archiveInfo.Flags = ReadUInt16(); // number of CFFILE entries in this cabinet
|
archiveInfo.Flags = ReadUInt16();
|
||||||
|
if (archiveInfo.Flags > 7)
|
||||||
|
return S_FALSE;
|
||||||
archiveInfo.SetID = ReadUInt16(); // must be the same for all cabinets in a set
|
archiveInfo.SetID = ReadUInt16(); // must be the same for all cabinets in a set
|
||||||
archiveInfo.CabinetNumber = ReadUInt16(); // number of this cabinet file in a set
|
archiveInfo.CabinetNumber = ReadUInt16(); // number of this cabinet file in a set
|
||||||
|
|
||||||
@@ -175,9 +156,9 @@ HRESULT CInArchive::Open2(IInStream *inStream,
|
|||||||
database.Folders.Add(folder);
|
database.Folders.Add(folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
RINOK(inStream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL));
|
RINOK(stream->Seek(database.StartPosition + archiveInfo.FileHeadersOffset, STREAM_SEEK_SET, NULL));
|
||||||
|
|
||||||
inBuffer.SetStream(inStream);
|
inBuffer.SetStream(stream);
|
||||||
inBuffer.Init();
|
inBuffer.Init();
|
||||||
for(i = 0; i < archiveInfo.NumFiles; i++)
|
for(i = 0; i < archiveInfo.NumFiles; i++)
|
||||||
{
|
{
|
||||||
@@ -221,8 +202,8 @@ static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
|
|||||||
const CDatabaseEx &db2 = mvDb.Volumes[p2->VolumeIndex];
|
const CDatabaseEx &db2 = mvDb.Volumes[p2->VolumeIndex];
|
||||||
const CItem &item1 = db1.Items[p1->ItemIndex];
|
const CItem &item1 = db1.Items[p1->ItemIndex];
|
||||||
const CItem &item2 = db2.Items[p2->ItemIndex];;
|
const CItem &item2 = db2.Items[p2->ItemIndex];;
|
||||||
bool isDir1 = item1.IsDirectory();
|
bool isDir1 = item1.IsDir();
|
||||||
bool isDir2 = item2.IsDirectory();
|
bool isDir2 = item2.IsDir();
|
||||||
if (isDir1 && !isDir2)
|
if (isDir1 && !isDir2)
|
||||||
return -1;
|
return -1;
|
||||||
if (isDir2 && !isDir1)
|
if (isDir2 && !isDir1)
|
||||||
@@ -322,7 +303,7 @@ bool CMvDatabaseEx::Check()
|
|||||||
if (fIndex >= FolderStartFileIndex.Size())
|
if (fIndex >= FolderStartFileIndex.Size())
|
||||||
return false;
|
return false;
|
||||||
const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||||
if (item.IsDirectory())
|
if (item.IsDir())
|
||||||
continue;
|
continue;
|
||||||
int folderIndex = GetFolderIndex(&mvItem);
|
int folderIndex = GetFolderIndex(&mvItem);
|
||||||
if (folderIndex != prevFolder)
|
if (folderIndex != prevFolder)
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int GetNumberOfNewFolders() const
|
int GetNumberOfNewFolders() const
|
||||||
{
|
{
|
||||||
int res = Folders.Size();
|
int res = Folders.Size();
|
||||||
if (IsTherePrevFolder())
|
if (IsTherePrevFolder())
|
||||||
@@ -124,10 +124,10 @@ public:
|
|||||||
CRecordVector<CMvItem> Items;
|
CRecordVector<CMvItem> Items;
|
||||||
CRecordVector<int> StartFolderOfVol;
|
CRecordVector<int> StartFolderOfVol;
|
||||||
CRecordVector<int> FolderStartFileIndex;
|
CRecordVector<int> FolderStartFileIndex;
|
||||||
int GetFolderIndex(const CMvItem *mvi) const
|
int GetFolderIndex(const CMvItem *mvi) const
|
||||||
{
|
{
|
||||||
const CDatabaseEx &db = Volumes[mvi->VolumeIndex];
|
const CDatabaseEx &db = Volumes[mvi->VolumeIndex];
|
||||||
return StartFolderOfVol[mvi->VolumeIndex] +
|
return StartFolderOfVol[mvi->VolumeIndex] +
|
||||||
db.Items[mvi->ItemIndex].GetFolderIndex(db.Folders.Size());
|
db.Items[mvi->ItemIndex].GetFolderIndex(db.Folders.Size());
|
||||||
}
|
}
|
||||||
void Clear()
|
void Clear()
|
||||||
@@ -152,7 +152,7 @@ class CInArchive
|
|||||||
void Skeep(size_t size);
|
void Skeep(size_t size);
|
||||||
void ReadOtherArchive(COtherArchive &oa);
|
void ReadOtherArchive(COtherArchive &oa);
|
||||||
|
|
||||||
HRESULT Open2(IInStream *inStream,
|
HRESULT Open2(IInStream *inStream,
|
||||||
const UInt64 *searchHeaderSizeLimit,
|
const UInt64 *searchHeaderSizeLimit,
|
||||||
CDatabase &database);
|
CDatabase &database);
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -19,9 +19,8 @@ struct CFolder
|
|||||||
Byte GetCompressionMethod() const { return (Byte)(CompressionTypeMajor & 0xF); }
|
Byte GetCompressionMethod() const { return (Byte)(CompressionTypeMajor & 0xF); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class CItem
|
struct CItem
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
AString Name;
|
AString Name;
|
||||||
UInt32 Offset;
|
UInt32 Offset;
|
||||||
UInt32 Size;
|
UInt32 Size;
|
||||||
@@ -29,26 +28,28 @@ public:
|
|||||||
UInt16 FolderIndex;
|
UInt16 FolderIndex;
|
||||||
UInt16 Flags;
|
UInt16 Flags;
|
||||||
UInt16 Attributes;
|
UInt16 Attributes;
|
||||||
|
|
||||||
UInt64 GetEndOffset() const { return (UInt64)Offset + Size; }
|
UInt64 GetEndOffset() const { return (UInt64)Offset + Size; }
|
||||||
UInt32 GetWinAttributes() const { return (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); }
|
UInt32 GetWinAttributes() const { return (Attributes & ~NHeader::kFileNameIsUTFAttributeMask); }
|
||||||
bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUTFAttributeMask) != 0; }
|
bool IsNameUTF() const { return (Attributes & NHeader::kFileNameIsUTFAttributeMask) != 0; }
|
||||||
bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
|
bool IsDir() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; }
|
||||||
|
|
||||||
bool ContinuedFromPrev() const
|
bool ContinuedFromPrev() const
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
(FolderIndex == NHeader::NFolderIndex::kContinuedFromPrev) ||
|
(FolderIndex == NHeader::NFolderIndex::kContinuedFromPrev) ||
|
||||||
(FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext);
|
(FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext);
|
||||||
}
|
}
|
||||||
bool ContinuedToNext() const
|
|
||||||
{
|
bool ContinuedToNext() const
|
||||||
return
|
{
|
||||||
|
return
|
||||||
(FolderIndex == NHeader::NFolderIndex::kContinuedToNext) ||
|
(FolderIndex == NHeader::NFolderIndex::kContinuedToNext) ||
|
||||||
(FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext);
|
(FolderIndex == NHeader::NFolderIndex::kContinuedPrevAndNext);
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetFolderIndex(int numFolders) const
|
int GetFolderIndex(int numFolders) const
|
||||||
{
|
{
|
||||||
if (ContinuedFromPrev())
|
if (ContinuedFromPrev())
|
||||||
return 0;
|
return 0;
|
||||||
if (ContinuedToNext())
|
if (ContinuedToNext())
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
// StdAfx.cpp
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
|
||||||
@@ -32,17 +32,16 @@ namespace NChm {
|
|||||||
|
|
||||||
#ifdef _CHM_DETAILS
|
#ifdef _CHM_DETAILS
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kpidSection = kpidUserDefined
|
kpidSection = kpidUserDefined
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
STATPROPSTG kProps[] =
|
STATPROPSTG kProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidPath, VT_BSTR},
|
{ NULL, kpidPath, VT_BSTR},
|
||||||
// { NULL, kpidIsFolder, VT_BOOL},
|
|
||||||
{ NULL, kpidSize, VT_UI8},
|
{ NULL, kpidSize, VT_UI8},
|
||||||
{ NULL, kpidMethod, VT_BSTR},
|
{ NULL, kpidMethod, VT_BSTR},
|
||||||
{ NULL, kpidBlock, VT_UI4}
|
{ NULL, kpidBlock, VT_UI4}
|
||||||
@@ -54,7 +53,7 @@ STATPROPSTG kProps[] =
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
STATPROPSTG kArcProps[] =
|
STATPROPSTG kArcProps[] =
|
||||||
{
|
{
|
||||||
{ NULL, kpidNumBlocks, VT_UI8}
|
{ NULL, kpidNumBlocks, VT_UI8}
|
||||||
};
|
};
|
||||||
@@ -71,7 +70,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
NWindows::NCOM::CPropVariant prop;
|
NWindows::NCOM::CPropVariant prop;
|
||||||
switch(propID)
|
switch(propID)
|
||||||
{
|
{
|
||||||
case kpidNumBlocks:
|
case kpidNumBlocks:
|
||||||
{
|
{
|
||||||
UInt64 numBlocks = 0;
|
UInt64 numBlocks = 0;
|
||||||
for (int i = 0; i < m_Database.Sections.Size(); i++)
|
for (int i = 0; i < m_Database.Sections.Size(); i++)
|
||||||
@@ -84,7 +83,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
numBlocks += m.LzxInfo.ResetTable.GetNumBlocks();
|
numBlocks += m.LzxInfo.ResetTable.GetNumBlocks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prop = numBlocks;
|
prop = numBlocks;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,15 +131,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kpidIsFolder:
|
case kpidIsDir: prop = item.IsDir(); break;
|
||||||
prop = item.IsDirectory();
|
case kpidSize: prop = item.Size; break;
|
||||||
break;
|
|
||||||
case kpidSize:
|
|
||||||
prop = item.Size;
|
|
||||||
break;
|
|
||||||
case kpidMethod:
|
case kpidMethod:
|
||||||
{
|
{
|
||||||
if (!item.IsDirectory())
|
if (!item.IsDir())
|
||||||
if (item.Section == 0)
|
if (item.Section == 0)
|
||||||
prop = L"Copy";
|
prop = L"Copy";
|
||||||
else if (item.Section < m_Database.Sections.Size())
|
else if (item.Section < m_Database.Sections.Size())
|
||||||
@@ -156,12 +151,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
|
|
||||||
#ifdef _CHM_DETAILS
|
#ifdef _CHM_DETAILS
|
||||||
|
|
||||||
case kpidSection:
|
case kpidSection: prop = (UInt32)item.Section; break;
|
||||||
prop = (UInt32)item.Section;
|
case kpidOffset: prop = (UInt32)item.Offset; break;
|
||||||
break;
|
|
||||||
case kpidOffset:
|
|
||||||
prop = (UInt32)item.Offset;
|
|
||||||
break;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -170,41 +161,39 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
|
|||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
class CPropgressImp: public CProgressVirt
|
class CProgressImp: public CProgressVirt
|
||||||
{
|
{
|
||||||
CMyComPtr<IArchiveOpenCallback> m_OpenArchiveCallback;
|
CMyComPtr<IArchiveOpenCallback> _callback;
|
||||||
public:
|
public:
|
||||||
STDMETHOD(SetTotal)(const UInt64 *numFiles);
|
STDMETHOD(SetTotal)(const UInt64 *numFiles);
|
||||||
STDMETHOD(SetCompleted)(const UInt64 *numFiles);
|
STDMETHOD(SetCompleted)(const UInt64 *numFiles);
|
||||||
void Init(IArchiveOpenCallback *openArchiveCallback)
|
CProgressImp(IArchiveOpenCallback *callback): _callback(callback) {};
|
||||||
{ m_OpenArchiveCallback = openArchiveCallback; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP CPropgressImp::SetTotal(const UInt64 *numFiles)
|
STDMETHODIMP CProgressImp::SetTotal(const UInt64 *numFiles)
|
||||||
{
|
{
|
||||||
if (m_OpenArchiveCallback)
|
if (_callback)
|
||||||
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
return _callback->SetCompleted(numFiles, NULL);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CPropgressImp::SetCompleted(const UInt64 *numFiles)
|
STDMETHODIMP CProgressImp::SetCompleted(const UInt64 *numFiles)
|
||||||
{
|
{
|
||||||
if (m_OpenArchiveCallback)
|
if (_callback)
|
||||||
return m_OpenArchiveCallback->SetCompleted(numFiles, NULL);
|
return _callback->SetCompleted(numFiles, NULL);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||||
const UInt64 *maxCheckStartPosition,
|
const UInt64 *maxCheckStartPosition,
|
||||||
IArchiveOpenCallback *openArchiveCallback)
|
IArchiveOpenCallback * /* openArchiveCallback */)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
m_Stream.Release();
|
m_Stream.Release();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
CInArchive archive;
|
CInArchive archive;
|
||||||
CPropgressImp progressImp;
|
// CProgressImp progressImp(openArchiveCallback);
|
||||||
progressImp.Init(openArchiveCallback);
|
|
||||||
RINOK(archive.Open(inStream, maxCheckStartPosition, m_Database));
|
RINOK(archive.Open(inStream, maxCheckStartPosition, m_Database));
|
||||||
/*
|
/*
|
||||||
if (m_Database.LowLevel)
|
if (m_Database.LowLevel)
|
||||||
@@ -227,7 +216,7 @@ STDMETHODIMP CHandler::Close()
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CChmFolderOutStream:
|
class CChmFolderOutStream:
|
||||||
public ISequentialOutStream,
|
public ISequentialOutStream,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
@@ -280,7 +269,7 @@ void CChmFolderOutStream::Init(
|
|||||||
|
|
||||||
HRESULT CChmFolderOutStream::OpenFile()
|
HRESULT CChmFolderOutStream::OpenFile()
|
||||||
{
|
{
|
||||||
Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ?
|
Int32 askMode = (*m_ExtractStatuses)[m_CurrentIndex] ? (m_TestMode ?
|
||||||
NExtract::NAskMode::kTest :
|
NExtract::NAskMode::kTest :
|
||||||
NExtract::NAskMode::kExtract) :
|
NExtract::NAskMode::kExtract) :
|
||||||
NExtract::NAskMode::kSkip;
|
NExtract::NAskMode::kSkip;
|
||||||
@@ -345,7 +334,7 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
|||||||
{
|
{
|
||||||
m_RealOutStream.Release();
|
m_RealOutStream.Release();
|
||||||
RINOK(m_ExtractCallback->SetOperationResult(
|
RINOK(m_ExtractCallback->SetOperationResult(
|
||||||
m_IsOk ?
|
m_IsOk ?
|
||||||
NArchive::NExtract::NOperationResult::kOK:
|
NArchive::NExtract::NOperationResult::kOK:
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
NArchive::NExtract::NOperationResult::kDataError));
|
||||||
m_FileIsOpen = false;
|
m_FileIsOpen = false;
|
||||||
@@ -356,7 +345,7 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_CurrentIndex >= m_NumFiles)
|
if (m_CurrentIndex >= m_NumFiles)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
int fullIndex = m_StartIndex + m_CurrentIndex;
|
int fullIndex = m_StartIndex + m_CurrentIndex;
|
||||||
m_RemainFileSize = m_Database->GetFileSize(fullIndex);
|
m_RemainFileSize = m_Database->GetFileSize(fullIndex);
|
||||||
UInt64 fileOffset = m_Database->GetFileOffset(fullIndex);
|
UInt64 fileOffset = m_Database->GetFileOffset(fullIndex);
|
||||||
@@ -458,7 +447,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
|
|
||||||
RINOK(lps->SetCur());
|
RINOK(lps->SetCur());
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
Int32 askMode= testMode ?
|
Int32 askMode= testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NArchive::NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NArchive::NExtract::NAskMode::kExtract;
|
||||||
Int32 index = allFilesMode ? i : indices[i];
|
Int32 index = allFilesMode ? i : indices[i];
|
||||||
@@ -502,7 +491,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
|
|
||||||
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
|
||||||
realOutStream.Release();
|
realOutStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
RINOK(extractCallback->SetOperationResult((copyCoderSpec->TotalSize == item.Size) ?
|
||||||
NArchive::NExtract::NOperationResult::kOK:
|
NArchive::NExtract::NOperationResult::kOK:
|
||||||
NArchive::NExtract::NOperationResult::kDataError));
|
NArchive::NExtract::NOperationResult::kDataError));
|
||||||
}
|
}
|
||||||
@@ -516,7 +505,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
int entryIndex = m_Database.Indices[index];
|
int entryIndex = m_Database.Indices[index];
|
||||||
const CItem &item = m_Database.Items[entryIndex];
|
const CItem &item = m_Database.Items[entryIndex];
|
||||||
UInt64 sectionIndex = item.Section;
|
UInt64 sectionIndex = item.Section;
|
||||||
if (item.IsDirectory() || item.Size == 0)
|
if (item.IsDir() || item.Size == 0)
|
||||||
continue;
|
continue;
|
||||||
if (sectionIndex == 0)
|
if (sectionIndex == 0)
|
||||||
{
|
{
|
||||||
@@ -554,10 +543,10 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
|||||||
int entryIndex = m_Database.Indices[index];
|
int entryIndex = m_Database.Indices[index];
|
||||||
const CItem &item = m_Database.Items[entryIndex];
|
const CItem &item = m_Database.Items[entryIndex];
|
||||||
UInt64 sectionIndex = item.Section;
|
UInt64 sectionIndex = item.Section;
|
||||||
Int32 askMode= testMode ?
|
Int32 askMode= testMode ?
|
||||||
NArchive::NExtract::NAskMode::kTest :
|
NArchive::NExtract::NAskMode::kTest :
|
||||||
NArchive::NExtract::NAskMode::kExtract;
|
NArchive::NExtract::NAskMode::kExtract;
|
||||||
if (item.IsDirectory())
|
if (item.IsDir())
|
||||||
{
|
{
|
||||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user