win32: switch 7z to an externally housed static library, same as zlib. clean up some source file license headers
This commit is contained in:
parent
8c62cc838a
commit
3b5ee1f29f
|
@ -1,7 +1,4 @@
|
|||
/* Copyright (C) 2006 yopyop
|
||||
yopyop156@ifrance.com
|
||||
yopyop156.ifrance.com
|
||||
|
||||
Copyright (C) 2006 Mic
|
||||
Copyright (C) 2009 CrazyMax
|
||||
Copyright (C) 2009 DeSmuME team
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/* Copyright (C) 2006 yopyop
|
||||
yopyop156@ifrance.com
|
||||
yopyop156.ifrance.com
|
||||
|
||||
Copyright (C) 2009 CrazyMax
|
||||
/* Copyright (C) 2009 CrazyMax
|
||||
Copyright (C) 2009 DeSmuME team
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/* Copyright (C) 2006 yopyop
|
||||
yopyop156@ifrance.com
|
||||
yopyop156.ifrance.com
|
||||
|
||||
Copyright (C) 2009 CrazyMax
|
||||
/* Copyright (C) 2009 CrazyMax
|
||||
Copyright (C) 2009 DeSmuME team
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/* Copyright (C) 2006 yopyop
|
||||
yopyop156@ifrance.com
|
||||
yopyop156.ifrance.com
|
||||
|
||||
Copyright (C) 2009 CrazyMax
|
||||
/* Copyright (C) 2009 CrazyMax
|
||||
Copyright (C) 2009 DeSmuME team
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/* Copyright (C) 2006 yopyop
|
||||
yopyop156@ifrance.com
|
||||
yopyop156.ifrance.com
|
||||
|
||||
Copyright (C) 2009 CrazyMax
|
||||
/* Copyright (C) 2009 CrazyMax
|
||||
Copyright (C) 2009 DeSmuME team
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/* Copyright (C) 2006 yopyop
|
||||
yopyop156@ifrance.com
|
||||
yopyop156.ifrance.com
|
||||
|
||||
Copyright (C) 2009 CrazyMax
|
||||
/* Copyright (C) 2009 CrazyMax
|
||||
Copyright (C) 2009 DeSmuME team
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//taken from ndstool
|
||||
//http://devkitpro.cvs.sourceforge.net/viewvc/devkitpro/tools/nds/ndstool/source/crc.cpp?revision=1.2
|
||||
//http://devkitpro.svn.sourceforge.net/viewvc/devkitpro/trunk/tools/nds/ndstool/source/crc.cpp?revision=1587
|
||||
|
||||
/* crc.cpp - this file is part of DeSmuME
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//taken from ndstool
|
||||
//http://devkitpro.cvs.sourceforge.net/viewvc/devkitpro/tools/nds/ndstool/include/crc.h?revision=1.3
|
||||
//http://devkitpro.svn.sourceforge.net/viewvc/devkitpro/trunk/tools/nds/ndstool/include/crc.h?revision=2447
|
||||
|
||||
/* crc.h - this file is part of DeSmuME
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//taken from ndstool
|
||||
//http://devkitpro.cvs.sourceforge.net/viewvc/devkitpro/tools/nds/ndstool/source/encryption.cpp?revision=1.2
|
||||
//http://devkitpro.svn.sourceforge.net/viewvc/devkitpro/trunk/tools/nds/ndstool/source/encryption.cpp?revision=1565
|
||||
|
||||
/* decrypt.cpp - this file is part of DeSmuME
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//taken from ndstool
|
||||
//http://devkitpro.cvs.sourceforge.net/viewvc/devkitpro/tools/nds/ndstool/source/header.cpp?revision=1.23
|
||||
//http://devkitpro.svn.sourceforge.net/viewvc/devkitpro/trunk/tools/nds/ndstool/source/header.cpp?revision=3063
|
||||
|
||||
/* header.cpp - this file is part of DeSmuME
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//taken from ndstool
|
||||
//http://devkitpro.cvs.sourceforge.net/viewvc/devkitpro/tools/nds/ndstool/include/header.h?revision=1.14
|
||||
//http://devkitpro.svn.sourceforge.net/viewvc/devkitpro/trunk/tools/nds/ndstool/include/header.h?revision=2447
|
||||
|
||||
/* header.h - this file is part of DeSmuME
|
||||
*
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,26 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib7zip", "7zip.vcproj", "{5646C572-A578-49F8-9DA9-3E00A8CBFE3F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{5646C572-A578-49F8-9DA9-3E00A8CBFE3F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{5646C572-A578-49F8-9DA9-3E00A8CBFE3F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{5646C572-A578-49F8-9DA9-3E00A8CBFE3F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{5646C572-A578-49F8-9DA9-3E00A8CBFE3F}.Debug|x64.Build.0 = Debug|x64
|
||||
{5646C572-A578-49F8-9DA9-3E00A8CBFE3F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{5646C572-A578-49F8-9DA9-3E00A8CBFE3F}.Release|Win32.Build.0 = Release|Win32
|
||||
{5646C572-A578-49F8-9DA9-3E00A8CBFE3F}.Release|x64.ActiveCfg = Release|x64
|
||||
{5646C572-A578-49F8-9DA9-3E00A8CBFE3F}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
File diff suppressed because it is too large
Load Diff
|
@ -1,35 +0,0 @@
|
|||
/* 7zCrc.c -- CRC32 calculation
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#include "7zCrc.h"
|
||||
|
||||
#define kCrcPoly 0xEDB88320
|
||||
UInt32 g_CrcTable[256];
|
||||
|
||||
void MY_FAST_CALL CrcGenerateTable(void)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
UInt32 r = i;
|
||||
int j;
|
||||
for (j = 0; j < 8; j++)
|
||||
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
||||
g_CrcTable[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
|
||||
{
|
||||
const Byte *p = (const Byte *)data;
|
||||
for (; size > 0 ; size--, p++)
|
||||
v = CRC_UPDATE_BYTE(v, *p);
|
||||
return v;
|
||||
}
|
||||
|
||||
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
|
||||
{
|
||||
return CrcUpdate(CRC_INIT_VAL, data, size) ^ 0xFFFFFFFF;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/* 7zCrc.h -- CRC32 calculation
|
||||
2008-03-13
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#ifndef __7Z_CRC_H
|
||||
#define __7Z_CRC_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
extern UInt32 g_CrcTable[];
|
||||
|
||||
void MY_FAST_CALL CrcGenerateTable(void);
|
||||
|
||||
#define CRC_INIT_VAL 0xFFFFFFFF
|
||||
#define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF)
|
||||
#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size);
|
||||
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
|
||||
|
||||
#endif
|
|
@ -1,262 +0,0 @@
|
|||
/* Aes.c -- AES encryption / decryption
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#include "Aes.h"
|
||||
#include "CpuArch.h"
|
||||
|
||||
static UInt32 T[256 * 4];
|
||||
static Byte Sbox[256] = {
|
||||
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,
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};
|
||||
|
||||
static UInt32 D[256 * 4];
|
||||
static Byte InvS[256];
|
||||
|
||||
static Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
|
||||
|
||||
#define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF)
|
||||
|
||||
#define Ui32(a0, a1, a2, a3) ((UInt32)(a0) | ((UInt32)(a1) << 8) | ((UInt32)(a2) << 16) | ((UInt32)(a3) << 24))
|
||||
|
||||
#define gb0(x) ( (x) & 0xFF)
|
||||
#define gb1(x) (((x) >> ( 8)) & 0xFF)
|
||||
#define gb2(x) (((x) >> (16)) & 0xFF)
|
||||
#define gb3(x) (((x) >> (24)) & 0xFF)
|
||||
|
||||
void AesGenTables(void)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < 256; i++)
|
||||
InvS[Sbox[i]] = (Byte)i;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
{
|
||||
UInt32 a1 = Sbox[i];
|
||||
UInt32 a2 = xtime(a1);
|
||||
UInt32 a3 = xtime(a1) ^ a1;
|
||||
T[ i] = Ui32(a2, a1, a1, a3);
|
||||
T[0x100 + i] = Ui32(a3, a2, a1, a1);
|
||||
T[0x200 + i] = Ui32(a1, a3, a2, a1);
|
||||
T[0x300 + i] = Ui32(a1, a1, a3, a2);
|
||||
}
|
||||
{
|
||||
UInt32 a1 = InvS[i];
|
||||
UInt32 a2 = xtime(a1);
|
||||
UInt32 a4 = xtime(a2);
|
||||
UInt32 a8 = xtime(a4);
|
||||
UInt32 a9 = a8 ^ a1;
|
||||
UInt32 aB = a8 ^ a2 ^ a1;
|
||||
UInt32 aD = a8 ^ a4 ^ a1;
|
||||
UInt32 aE = a8 ^ a4 ^ a2;
|
||||
D[ i] = Ui32(aE, a9, aD, aB);
|
||||
D[0x100 + i] = Ui32(aB, aE, a9, aD);
|
||||
D[0x200 + i] = Ui32(aD, aB, aE, a9);
|
||||
D[0x300 + i] = Ui32(a9, aD, aB, aE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define HT(i, x, s) (T + (x << 8))[gb ## x(s[(i + x) & 3])]
|
||||
#define HT4(m, i, s, p) m[i] = \
|
||||
HT(i, 0, s) ^ \
|
||||
HT(i, 1, s) ^ \
|
||||
HT(i, 2, s) ^ \
|
||||
HT(i, 3, s) ^ w[p + i]
|
||||
/* such order (2031) in HT16 is for VC6/K8 speed optimization) */
|
||||
#define HT16(m, s, p) \
|
||||
HT4(m, 2, s, p); \
|
||||
HT4(m, 0, s, p); \
|
||||
HT4(m, 3, s, p); \
|
||||
HT4(m, 1, s, p); \
|
||||
|
||||
#define FT(i, x) Sbox[gb ## x(m[(i + x) & 3])]
|
||||
#define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i];
|
||||
|
||||
#define HD(i, x, s) (D + (x << 8))[gb ## x(s[(i - x) & 3])]
|
||||
#define HD4(m, i, s, p) m[i] = \
|
||||
HD(i, 0, s) ^ \
|
||||
HD(i, 1, s) ^ \
|
||||
HD(i, 2, s) ^ \
|
||||
HD(i, 3, s) ^ w[p + i];
|
||||
/* such order (0231) in HD16 is for VC6/K8 speed optimization) */
|
||||
#define HD16(m, s, p) \
|
||||
HD4(m, 0, s, p); \
|
||||
HD4(m, 2, s, p); \
|
||||
HD4(m, 3, s, p); \
|
||||
HD4(m, 1, s, p); \
|
||||
|
||||
#define FD(i, x) InvS[gb ## x(m[(i - x) & 3])]
|
||||
#define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i];
|
||||
|
||||
void Aes_SetKeyEncode(CAes *p, const Byte *key, unsigned keySize)
|
||||
{
|
||||
unsigned i, wSize;
|
||||
UInt32 *w;
|
||||
keySize /= 4;
|
||||
p->numRounds2 = keySize / 2 + 3;
|
||||
|
||||
wSize = (p->numRounds2 * 2 + 1) * 4;
|
||||
w = p->rkey;
|
||||
|
||||
for (i = 0; i < keySize; i++, key += 4)
|
||||
w[i] = Ui32(key[0], key[1], key[2], key[3]);
|
||||
|
||||
for (; i < wSize; i++)
|
||||
{
|
||||
UInt32 t = w[i - 1];
|
||||
unsigned rem = i % keySize;
|
||||
if (rem == 0)
|
||||
t = Ui32(Sbox[gb1(t)] ^ Rcon[i / keySize], Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]);
|
||||
else if (keySize > 6 && rem == 4)
|
||||
t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]);
|
||||
w[i] = w[i - keySize] ^ t;
|
||||
}
|
||||
}
|
||||
|
||||
void Aes_SetKeyDecode(CAes *p, const Byte *key, unsigned keySize)
|
||||
{
|
||||
unsigned i, num;
|
||||
UInt32 *w;
|
||||
Aes_SetKeyEncode(p, key, keySize);
|
||||
num = p->numRounds2 * 8 - 4;
|
||||
w = p->rkey + 4;
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
UInt32 r = w[i];
|
||||
w[i] =
|
||||
D[ Sbox[gb0(r)]] ^
|
||||
D[0x100 + Sbox[gb1(r)]] ^
|
||||
D[0x200 + Sbox[gb2(r)]] ^
|
||||
D[0x300 + Sbox[gb3(r)]];
|
||||
}
|
||||
}
|
||||
|
||||
static void AesEncode32(UInt32 *dest, const UInt32 *src, const UInt32 *w, unsigned numRounds2)
|
||||
{
|
||||
UInt32 s[4];
|
||||
UInt32 m[4];
|
||||
s[0] = src[0] ^ w[0];
|
||||
s[1] = src[1] ^ w[1];
|
||||
s[2] = src[2] ^ w[2];
|
||||
s[3] = src[3] ^ w[3];
|
||||
w += 4;
|
||||
for (;;)
|
||||
{
|
||||
HT16(m, s, 0);
|
||||
if (--numRounds2 == 0)
|
||||
break;
|
||||
HT16(s, m, 4);
|
||||
w += 8;
|
||||
}
|
||||
w += 4;
|
||||
FT4(0); FT4(1); FT4(2); FT4(3);
|
||||
}
|
||||
|
||||
static void AesDecode32(UInt32 *dest, const UInt32 *src, const UInt32 *w, unsigned numRounds2)
|
||||
{
|
||||
UInt32 s[4];
|
||||
UInt32 m[4];
|
||||
w += numRounds2 * 8;
|
||||
s[0] = src[0] ^ w[0];
|
||||
s[1] = src[1] ^ w[1];
|
||||
s[2] = src[2] ^ w[2];
|
||||
s[3] = src[3] ^ w[3];
|
||||
for (;;)
|
||||
{
|
||||
w -= 8;
|
||||
HD16(m, s, 4);
|
||||
if (--numRounds2 == 0)
|
||||
break;
|
||||
HD16(s, m, 0);
|
||||
}
|
||||
FD4(0); FD4(1); FD4(2); FD4(3);
|
||||
}
|
||||
|
||||
void Aes_Encode32(const CAes *p, UInt32 *dest, const UInt32 *src)
|
||||
{
|
||||
AesEncode32(dest, src, p->rkey, p->numRounds2);
|
||||
}
|
||||
|
||||
void Aes_Decode32(const CAes *p, UInt32 *dest, const UInt32 *src)
|
||||
{
|
||||
AesDecode32(dest, src, p->rkey, p->numRounds2);
|
||||
}
|
||||
|
||||
void AesCbc_Init(CAesCbc *p, const Byte *iv)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < 4; i++)
|
||||
p->prev[i] = GetUi32(iv + i * 4);
|
||||
}
|
||||
|
||||
SizeT AesCbc_Encode(CAesCbc *p, Byte *data, SizeT size)
|
||||
{
|
||||
SizeT i;
|
||||
if (size == 0)
|
||||
return 0;
|
||||
if (size < AES_BLOCK_SIZE)
|
||||
return AES_BLOCK_SIZE;
|
||||
size -= AES_BLOCK_SIZE;
|
||||
for (i = 0; i <= size; i += AES_BLOCK_SIZE, data += AES_BLOCK_SIZE)
|
||||
{
|
||||
p->prev[0] ^= GetUi32(data);
|
||||
p->prev[1] ^= GetUi32(data + 4);
|
||||
p->prev[2] ^= GetUi32(data + 8);
|
||||
p->prev[3] ^= GetUi32(data + 12);
|
||||
|
||||
AesEncode32(p->prev, p->prev, p->aes.rkey, p->aes.numRounds2);
|
||||
|
||||
SetUi32(data, p->prev[0]);
|
||||
SetUi32(data + 4, p->prev[1]);
|
||||
SetUi32(data + 8, p->prev[2]);
|
||||
SetUi32(data + 12, p->prev[3]);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SizeT AesCbc_Decode(CAesCbc *p, Byte *data, SizeT size)
|
||||
{
|
||||
SizeT i;
|
||||
UInt32 in[4], out[4];
|
||||
if (size == 0)
|
||||
return 0;
|
||||
if (size < AES_BLOCK_SIZE)
|
||||
return AES_BLOCK_SIZE;
|
||||
size -= AES_BLOCK_SIZE;
|
||||
for (i = 0; i <= size; i += AES_BLOCK_SIZE, data += AES_BLOCK_SIZE)
|
||||
{
|
||||
in[0] = GetUi32(data);
|
||||
in[1] = GetUi32(data + 4);
|
||||
in[2] = GetUi32(data + 8);
|
||||
in[3] = GetUi32(data + 12);
|
||||
|
||||
AesDecode32(out, in, p->aes.rkey, p->aes.numRounds2);
|
||||
|
||||
SetUi32(data, p->prev[0] ^ out[0]);
|
||||
SetUi32(data + 4, p->prev[1] ^ out[1]);
|
||||
SetUi32(data + 8, p->prev[2] ^ out[2]);
|
||||
SetUi32(data + 12, p->prev[3] ^ out[3]);
|
||||
|
||||
p->prev[0] = in[0];
|
||||
p->prev[1] = in[1];
|
||||
p->prev[2] = in[2];
|
||||
p->prev[3] = in[3];
|
||||
}
|
||||
return i;
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/* Aes.h -- AES encryption / decryption
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#ifndef __AES_H
|
||||
#define __AES_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned numRounds2; /* = numRounds / 2 */
|
||||
UInt32 rkey[(14 + 1) * 4];
|
||||
} CAes;
|
||||
|
||||
/* Call AesGenTables one time before other AES functions */
|
||||
void AesGenTables(void);
|
||||
|
||||
/* keySize = 16 or 24 or 32 (bytes) */
|
||||
void Aes_SetKeyEncode(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.
|
||||
src and dest are pointers to 4 UInt32 words.
|
||||
arc and dest can point to same block */
|
||||
void Aes_Encode32(const CAes *p, UInt32 *dest, const UInt32 *src);
|
||||
void Aes_Decode32(const CAes *p, UInt32 *dest, const UInt32 *src);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 prev[4];
|
||||
CAes aes;
|
||||
} CAesCbc;
|
||||
|
||||
void AesCbc_Init(CAesCbc *p, const Byte *iv); /* iv size is AES_BLOCK_SIZE */
|
||||
|
||||
/* AesCbc_Encode and AesCbc_Decode:
|
||||
if (res <= size): Filter have converted res bytes
|
||||
if (res > size): Filter have not converted anything. And it needs at
|
||||
least res = AES_BLOCK_SIZE bytes to convert one block */
|
||||
|
||||
SizeT AesCbc_Encode(CAesCbc *p, Byte *data, SizeT size);
|
||||
SizeT AesCbc_Decode(CAesCbc *p, Byte *data, SizeT size);
|
||||
|
||||
#endif
|
|
@ -1,127 +0,0 @@
|
|||
/* Alloc.c -- Memory allocation functions
|
||||
2008-09-24
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Alloc.h"
|
||||
|
||||
/* #define _SZ_ALLOC_DEBUG */
|
||||
|
||||
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
#include <stdio.h>
|
||||
int g_allocCount = 0;
|
||||
int g_allocCountMid = 0;
|
||||
int g_allocCountBig = 0;
|
||||
#endif
|
||||
|
||||
void *MyAlloc(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
{
|
||||
void *p = malloc(size);
|
||||
fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p);
|
||||
return p;
|
||||
}
|
||||
#else
|
||||
return malloc(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MyFree(void *address)
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);
|
||||
#endif
|
||||
free(address);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void *MidAlloc(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
|
||||
#endif
|
||||
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
void MidFree(void *address)
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
|
||||
#endif
|
||||
if (address == 0)
|
||||
return;
|
||||
VirtualFree(address, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
#ifndef MEM_LARGE_PAGES
|
||||
#undef _7ZIP_LARGE_PAGES
|
||||
#endif
|
||||
|
||||
#ifdef _7ZIP_LARGE_PAGES
|
||||
SIZE_T g_LargePageSize = 0;
|
||||
typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
|
||||
#endif
|
||||
|
||||
void SetLargePageSize()
|
||||
{
|
||||
#ifdef _7ZIP_LARGE_PAGES
|
||||
SIZE_T size = 0;
|
||||
GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
|
||||
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
|
||||
if (largePageMinimum == 0)
|
||||
return;
|
||||
size = largePageMinimum();
|
||||
if (size == 0 || (size & (size - 1)) != 0)
|
||||
return;
|
||||
g_LargePageSize = size;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void *BigAlloc(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
|
||||
#endif
|
||||
|
||||
#ifdef _7ZIP_LARGE_PAGES
|
||||
if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
|
||||
{
|
||||
void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
|
||||
MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
|
||||
if (res != 0)
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
void BigFree(void *address)
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
|
||||
#endif
|
||||
|
||||
if (address == 0)
|
||||
return;
|
||||
VirtualFree(address, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,32 +0,0 @@
|
|||
/* Alloc.h -- Memory allocation functions
|
||||
2008-03-13
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#ifndef __COMMON_ALLOC_H
|
||||
#define __COMMON_ALLOC_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void *MyAlloc(size_t size);
|
||||
void MyFree(void *address);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void SetLargePageSize();
|
||||
|
||||
void *MidAlloc(size_t size);
|
||||
void MidFree(void *address);
|
||||
void *BigAlloc(size_t size);
|
||||
void BigFree(void *address);
|
||||
|
||||
#else
|
||||
|
||||
#define MidAlloc(size) MyAlloc(size)
|
||||
#define MidFree(address) MyFree(address)
|
||||
#define BigAlloc(size) MyAlloc(size)
|
||||
#define BigFree(address) MyFree(address)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,133 +0,0 @@
|
|||
/* Bra.c -- Converters for RISC code
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Bra.h"
|
||||
|
||||
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
ip += 8;
|
||||
for (i = 0; i <= size; i += 4)
|
||||
{
|
||||
if (data[i + 3] == 0xEB)
|
||||
{
|
||||
UInt32 dest;
|
||||
UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
|
||||
src <<= 2;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
dest >>= 2;
|
||||
data[i + 2] = (Byte)(dest >> 16);
|
||||
data[i + 1] = (Byte)(dest >> 8);
|
||||
data[i + 0] = (Byte)dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
ip += 4;
|
||||
for (i = 0; i <= size; i += 2)
|
||||
{
|
||||
if ((data[i + 1] & 0xF8) == 0xF0 &&
|
||||
(data[i + 3] & 0xF8) == 0xF8)
|
||||
{
|
||||
UInt32 dest;
|
||||
UInt32 src =
|
||||
(((UInt32)data[i + 1] & 0x7) << 19) |
|
||||
((UInt32)data[i + 0] << 11) |
|
||||
(((UInt32)data[i + 3] & 0x7) << 8) |
|
||||
(data[i + 2]);
|
||||
|
||||
src <<= 1;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
dest >>= 1;
|
||||
|
||||
data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
|
||||
data[i + 0] = (Byte)(dest >> 11);
|
||||
data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
|
||||
data[i + 2] = (Byte)dest;
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
for (i = 0; i <= size; i += 4)
|
||||
{
|
||||
if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
|
||||
{
|
||||
UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
|
||||
((UInt32)data[i + 1] << 16) |
|
||||
((UInt32)data[i + 2] << 8) |
|
||||
((UInt32)data[i + 3] & (~3));
|
||||
|
||||
UInt32 dest;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3));
|
||||
data[i + 1] = (Byte)(dest >> 16);
|
||||
data[i + 2] = (Byte)(dest >> 8);
|
||||
data[i + 3] &= 0x3;
|
||||
data[i + 3] |= dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
UInt32 i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
for (i = 0; i <= size; i += 4)
|
||||
{
|
||||
if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 ||
|
||||
data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)
|
||||
{
|
||||
UInt32 src =
|
||||
((UInt32)data[i + 0] << 24) |
|
||||
((UInt32)data[i + 1] << 16) |
|
||||
((UInt32)data[i + 2] << 8) |
|
||||
((UInt32)data[i + 3]);
|
||||
UInt32 dest;
|
||||
|
||||
src <<= 2;
|
||||
if (encoding)
|
||||
dest = ip + i + src;
|
||||
else
|
||||
dest = src - (ip + i);
|
||||
dest >>= 2;
|
||||
|
||||
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
|
||||
|
||||
data[i + 0] = (Byte)(dest >> 24);
|
||||
data[i + 1] = (Byte)(dest >> 16);
|
||||
data[i + 2] = (Byte)(dest >> 8);
|
||||
data[i + 3] = (Byte)dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/* Bra.h -- Branch converters for executables
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __BRA_H
|
||||
#define __BRA_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
/*
|
||||
These functions convert relative addresses to absolute addresses
|
||||
in CALL instructions to increase the compression ratio.
|
||||
|
||||
In:
|
||||
data - data buffer
|
||||
size - size of data
|
||||
ip - current virtual Instruction Pinter (IP) value
|
||||
state - state variable for x86 converter
|
||||
encoding - 0 (for decoding), 1 (for encoding)
|
||||
|
||||
Out:
|
||||
state - state variable for x86 converter
|
||||
|
||||
Returns:
|
||||
The number of processed bytes. If you call these functions with multiple calls,
|
||||
you must start next call with first byte after block of processed bytes.
|
||||
|
||||
Type Endian Alignment LookAhead
|
||||
|
||||
x86 little 1 4
|
||||
ARMT little 2 2
|
||||
ARM little 4 0
|
||||
PPC big 4 0
|
||||
SPARC big 4 0
|
||||
IA64 little 16 0
|
||||
|
||||
size must be >= Alignment + LookAhead, if it's not last block.
|
||||
If (size < Alignment + LookAhead), converter returns 0.
|
||||
|
||||
Example:
|
||||
|
||||
UInt32 ip = 0;
|
||||
for ()
|
||||
{
|
||||
; size must be >= Alignment + LookAhead, if it's not last block
|
||||
SizeT processed = Convert(data, size, ip, 1);
|
||||
data += processed;
|
||||
size -= processed;
|
||||
ip += processed;
|
||||
}
|
||||
*/
|
||||
|
||||
#define x86_Convert_Init(state) { state = 0; }
|
||||
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
|
||||
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
|
||||
#endif
|
|
@ -1,85 +0,0 @@
|
|||
/* Bra86.c -- Converter for x86 code (BCJ)
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Bra.h"
|
||||
|
||||
#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
|
||||
|
||||
const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
|
||||
const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
|
||||
|
||||
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
|
||||
{
|
||||
SizeT bufferPos = 0, prevPosT;
|
||||
UInt32 prevMask = *state & 0x7;
|
||||
if (size < 5)
|
||||
return 0;
|
||||
ip += 5;
|
||||
prevPosT = (SizeT)0 - 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte *p = data + bufferPos;
|
||||
Byte *limit = data + size - 4;
|
||||
for (; p < limit; p++)
|
||||
if ((*p & 0xFE) == 0xE8)
|
||||
break;
|
||||
bufferPos = (SizeT)(p - data);
|
||||
if (p >= limit)
|
||||
break;
|
||||
prevPosT = bufferPos - prevPosT;
|
||||
if (prevPosT > 3)
|
||||
prevMask = 0;
|
||||
else
|
||||
{
|
||||
prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
|
||||
if (prevMask != 0)
|
||||
{
|
||||
Byte b = p[4 - kMaskToBitNumber[prevMask]];
|
||||
if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
|
||||
{
|
||||
prevPosT = bufferPos;
|
||||
prevMask = ((prevMask << 1) & 0x7) | 1;
|
||||
bufferPos++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
prevPosT = bufferPos;
|
||||
|
||||
if (Test86MSByte(p[4]))
|
||||
{
|
||||
UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
|
||||
UInt32 dest;
|
||||
for (;;)
|
||||
{
|
||||
Byte b;
|
||||
int index;
|
||||
if (encoding)
|
||||
dest = (ip + (UInt32)bufferPos) + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)bufferPos);
|
||||
if (prevMask == 0)
|
||||
break;
|
||||
index = kMaskToBitNumber[prevMask] * 8;
|
||||
b = (Byte)((dest >> (24 - index)) & 0xFF);
|
||||
if (!Test86MSByte(b))
|
||||
break;
|
||||
src = dest ^ ((1 << (32 - index)) - 1);
|
||||
}
|
||||
p[4] = (Byte)((~(((dest >> 24) & 1) - 1)) & 0xFF);
|
||||
p[3] = (Byte)((dest >> 16) & 0xFF);
|
||||
p[2] = (Byte)((dest >> 8) & 0xFF);
|
||||
p[1] = (Byte)(dest & 0xFF);
|
||||
bufferPos += 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevMask = ((prevMask << 1) & 0x7) | 1;
|
||||
bufferPos++;
|
||||
}
|
||||
}
|
||||
prevPosT = bufferPos - prevPosT;
|
||||
*state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
|
||||
return bufferPos;
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/* BraIA64.c -- Converter for IA-64 code
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Bra.h"
|
||||
|
||||
static const Byte kBranchTable[32] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
4, 4, 6, 6, 0, 0, 7, 7,
|
||||
4, 4, 0, 0, 4, 4, 0, 0
|
||||
};
|
||||
|
||||
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 16)
|
||||
return 0;
|
||||
size -= 16;
|
||||
for (i = 0; i <= size; i += 16)
|
||||
{
|
||||
UInt32 instrTemplate = data[i] & 0x1F;
|
||||
UInt32 mask = kBranchTable[instrTemplate];
|
||||
UInt32 bitPos = 5;
|
||||
int slot;
|
||||
for (slot = 0; slot < 3; slot++, bitPos += 41)
|
||||
{
|
||||
UInt32 bytePos, bitRes;
|
||||
UInt64 instruction, instNorm;
|
||||
int j;
|
||||
if (((mask >> slot) & 1) == 0)
|
||||
continue;
|
||||
bytePos = (bitPos >> 3);
|
||||
bitRes = bitPos & 0x7;
|
||||
instruction = 0;
|
||||
for (j = 0; j < 6; j++)
|
||||
instruction += (UInt64)data[i + j + bytePos] << (8 * j);
|
||||
|
||||
instNorm = instruction >> bitRes;
|
||||
if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0)
|
||||
{
|
||||
UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF);
|
||||
UInt32 dest;
|
||||
src |= ((UInt32)(instNorm >> 36) & 1) << 20;
|
||||
|
||||
src <<= 4;
|
||||
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
|
||||
dest >>= 4;
|
||||
|
||||
instNorm &= ~((UInt64)(0x8FFFFF) << 13);
|
||||
instNorm |= ((UInt64)(dest & 0xFFFFF) << 13);
|
||||
instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20));
|
||||
|
||||
instruction &= (1 << bitRes) - 1;
|
||||
instruction |= (instNorm << bitRes);
|
||||
for (j = 0; j < 6; j++)
|
||||
data[i + j + bytePos] = (Byte)(instruction >> (8 * j));
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
|
@ -1,516 +0,0 @@
|
|||
/* BwtSort.c -- BWT block sorting
|
||||
2008-08-17
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#include "BwtSort.h"
|
||||
#include "Sort.h"
|
||||
|
||||
/* #define BLOCK_SORT_USE_HEAP_SORT */
|
||||
|
||||
#define NO_INLINE MY_FAST_CALL
|
||||
|
||||
/* Don't change it !!! */
|
||||
#define kNumHashBytes 2
|
||||
#define kNumHashValues (1 << (kNumHashBytes * 8))
|
||||
|
||||
/* kNumRefBitsMax must be < (kNumHashBytes * 8) = 16 */
|
||||
#define kNumRefBitsMax 12
|
||||
|
||||
#define BS_TEMP_SIZE kNumHashValues
|
||||
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
|
||||
/* 32 Flags in UInt32 word */
|
||||
#define kNumFlagsBits 5
|
||||
#define kNumFlagsInWord (1 << kNumFlagsBits)
|
||||
#define kFlagsMask (kNumFlagsInWord - 1)
|
||||
#define kAllFlags 0xFFFFFFFF
|
||||
|
||||
#else
|
||||
|
||||
#define kNumBitsMax 20
|
||||
#define kIndexMask ((1 << kNumBitsMax) - 1)
|
||||
#define kNumExtraBits (32 - kNumBitsMax)
|
||||
#define kNumExtra0Bits (kNumExtraBits - 2)
|
||||
#define kNumExtra0Mask ((1 << kNumExtra0Bits) - 1)
|
||||
|
||||
#define SetFinishedGroupSize(p, size) \
|
||||
{ *(p) |= ((((size) - 1) & kNumExtra0Mask) << kNumBitsMax); \
|
||||
if ((size) > (1 << kNumExtra0Bits)) { \
|
||||
*(p) |= 0x40000000; *((p) + 1) |= ((((size) - 1)>> kNumExtra0Bits) << kNumBitsMax); } } \
|
||||
|
||||
static void SetGroupSize(UInt32 *p, UInt32 size)
|
||||
{
|
||||
if (--size == 0)
|
||||
return;
|
||||
*p |= 0x80000000 | ((size & kNumExtra0Mask) << kNumBitsMax);
|
||||
if (size >= (1 << kNumExtra0Bits))
|
||||
{
|
||||
*p |= 0x40000000;
|
||||
p[1] |= ((size >> kNumExtra0Bits) << kNumBitsMax);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
SortGroup - is recursive Range-Sort function with HeapSort optimization for small blocks
|
||||
"range" is not real range. It's only for optimization.
|
||||
returns: 1 - if there are groups, 0 - no more groups
|
||||
*/
|
||||
|
||||
UInt32 NO_INLINE SortGroup(UInt32 BlockSize, UInt32 NumSortedBytes, UInt32 groupOffset, UInt32 groupSize, int NumRefBits, UInt32 *Indices
|
||||
#ifndef BLOCK_SORT_USE_HEAP_SORT
|
||||
, UInt32 left, UInt32 range
|
||||
#endif
|
||||
)
|
||||
{
|
||||
UInt32 *ind2 = Indices + groupOffset;
|
||||
UInt32 *Groups;
|
||||
if (groupSize <= 1)
|
||||
{
|
||||
/*
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
SetFinishedGroupSize(ind2, 1);
|
||||
#endif
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
Groups = Indices + BlockSize + BS_TEMP_SIZE;
|
||||
if (groupSize <= ((UInt32)1 << NumRefBits)
|
||||
#ifndef BLOCK_SORT_USE_HEAP_SORT
|
||||
&& groupSize <= range
|
||||
#endif
|
||||
)
|
||||
{
|
||||
UInt32 *temp = Indices + BlockSize;
|
||||
UInt32 j;
|
||||
UInt32 mask, thereAreGroups, group, cg;
|
||||
{
|
||||
UInt32 gPrev;
|
||||
UInt32 gRes = 0;
|
||||
{
|
||||
UInt32 sp = ind2[0] + NumSortedBytes;
|
||||
if (sp >= BlockSize) sp -= BlockSize;
|
||||
gPrev = Groups[sp];
|
||||
temp[0] = (gPrev << NumRefBits);
|
||||
}
|
||||
|
||||
for (j = 1; j < groupSize; j++)
|
||||
{
|
||||
UInt32 sp = ind2[j] + NumSortedBytes;
|
||||
UInt32 g;
|
||||
if (sp >= BlockSize) sp -= BlockSize;
|
||||
g = Groups[sp];
|
||||
temp[j] = (g << NumRefBits) | j;
|
||||
gRes |= (gPrev ^ g);
|
||||
}
|
||||
if (gRes == 0)
|
||||
{
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
SetGroupSize(ind2, groupSize);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
HeapSort(temp, groupSize);
|
||||
mask = ((1 << NumRefBits) - 1);
|
||||
thereAreGroups = 0;
|
||||
|
||||
group = groupOffset;
|
||||
cg = (temp[0] >> NumRefBits);
|
||||
temp[0] = ind2[temp[0] & mask];
|
||||
|
||||
{
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
UInt32 *Flags = Groups + BlockSize;
|
||||
#else
|
||||
UInt32 prevGroupStart = 0;
|
||||
#endif
|
||||
|
||||
for (j = 1; j < groupSize; j++)
|
||||
{
|
||||
UInt32 val = temp[j];
|
||||
UInt32 cgCur = (val >> NumRefBits);
|
||||
|
||||
if (cgCur != cg)
|
||||
{
|
||||
cg = cgCur;
|
||||
group = groupOffset + j;
|
||||
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
{
|
||||
UInt32 t = group - 1;
|
||||
Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
|
||||
}
|
||||
#else
|
||||
SetGroupSize(temp + prevGroupStart, j - prevGroupStart);
|
||||
prevGroupStart = j;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
thereAreGroups = 1;
|
||||
{
|
||||
UInt32 ind = ind2[val & mask];
|
||||
temp[j] = ind;
|
||||
Groups[ind] = group;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
SetGroupSize(temp + prevGroupStart, j - prevGroupStart);
|
||||
#endif
|
||||
}
|
||||
|
||||
for (j = 0; j < groupSize; j++)
|
||||
ind2[j] = temp[j];
|
||||
return thereAreGroups;
|
||||
}
|
||||
|
||||
/* Check that all strings are in one group (cannot sort) */
|
||||
{
|
||||
UInt32 group, j;
|
||||
UInt32 sp = ind2[0] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize;
|
||||
group = Groups[sp];
|
||||
for (j = 1; j < groupSize; j++)
|
||||
{
|
||||
sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize;
|
||||
if (Groups[sp] != group)
|
||||
break;
|
||||
}
|
||||
if (j == groupSize)
|
||||
{
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
SetGroupSize(ind2, groupSize);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BLOCK_SORT_USE_HEAP_SORT
|
||||
{
|
||||
/* ---------- Range Sort ---------- */
|
||||
UInt32 i;
|
||||
UInt32 mid;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 j;
|
||||
if (range <= 1)
|
||||
{
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
SetGroupSize(ind2, groupSize);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
mid = left + ((range + 1) >> 1);
|
||||
j = groupSize;
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
UInt32 sp = ind2[i] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize;
|
||||
if (Groups[sp] >= mid)
|
||||
{
|
||||
for (j--; j > i; j--)
|
||||
{
|
||||
sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize;
|
||||
if (Groups[sp] < mid)
|
||||
{
|
||||
UInt32 temp = ind2[i]; ind2[i] = ind2[j]; ind2[j] = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= j)
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (++i < j);
|
||||
if (i == 0)
|
||||
{
|
||||
range = range - (mid - left);
|
||||
left = mid;
|
||||
}
|
||||
else if (i == groupSize)
|
||||
range = (mid - left);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
{
|
||||
UInt32 t = (groupOffset + i - 1);
|
||||
UInt32 *Flags = Groups + BlockSize;
|
||||
Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
UInt32 j;
|
||||
for (j = i; j < groupSize; j++)
|
||||
Groups[ind2[j]] = groupOffset + i;
|
||||
}
|
||||
|
||||
{
|
||||
UInt32 res = SortGroup(BlockSize, NumSortedBytes, groupOffset, i, NumRefBits, Indices, left, mid - left);
|
||||
return res | SortGroup(BlockSize, NumSortedBytes, groupOffset + i, groupSize - i, NumRefBits, Indices, mid, range - (mid - left));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* ---------- Heap Sort ---------- */
|
||||
|
||||
{
|
||||
UInt32 j;
|
||||
for (j = 0; j < groupSize; j++)
|
||||
{
|
||||
UInt32 sp = ind2[j] + NumSortedBytes; if (sp >= BlockSize) sp -= BlockSize;
|
||||
ind2[j] = sp;
|
||||
}
|
||||
|
||||
HeapSortRef(ind2, Groups, groupSize);
|
||||
|
||||
/* Write Flags */
|
||||
{
|
||||
UInt32 sp = ind2[0];
|
||||
UInt32 group = Groups[sp];
|
||||
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
UInt32 *Flags = Groups + BlockSize;
|
||||
#else
|
||||
UInt32 prevGroupStart = 0;
|
||||
#endif
|
||||
|
||||
for (j = 1; j < groupSize; j++)
|
||||
{
|
||||
sp = ind2[j];
|
||||
if (Groups[sp] != group)
|
||||
{
|
||||
group = Groups[sp];
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
{
|
||||
UInt32 t = groupOffset + j - 1;
|
||||
Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
|
||||
}
|
||||
#else
|
||||
SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart);
|
||||
prevGroupStart = j;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
SetGroupSize(ind2 + prevGroupStart, j - prevGroupStart);
|
||||
#endif
|
||||
}
|
||||
{
|
||||
/* Write new Groups values and Check that there are groups */
|
||||
UInt32 thereAreGroups = 0;
|
||||
for (j = 0; j < groupSize; j++)
|
||||
{
|
||||
UInt32 group = groupOffset + j;
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
UInt32 subGroupSize = ((ind2[j] & ~0xC0000000) >> kNumBitsMax);
|
||||
if ((ind2[j] & 0x40000000) != 0)
|
||||
subGroupSize += ((ind2[j + 1] >> kNumBitsMax) << kNumExtra0Bits);
|
||||
subGroupSize++;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 original = ind2[j];
|
||||
UInt32 sp = original & kIndexMask;
|
||||
if (sp < NumSortedBytes) sp += BlockSize; sp -= NumSortedBytes;
|
||||
ind2[j] = sp | (original & ~kIndexMask);
|
||||
Groups[sp] = group;
|
||||
if (--subGroupSize == 0)
|
||||
break;
|
||||
j++;
|
||||
thereAreGroups = 1;
|
||||
}
|
||||
#else
|
||||
UInt32 *Flags = Groups + BlockSize;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 sp = ind2[j]; if (sp < NumSortedBytes) sp += BlockSize; sp -= NumSortedBytes;
|
||||
ind2[j] = sp;
|
||||
Groups[sp] = group;
|
||||
if ((Flags[(groupOffset + j) >> kNumFlagsBits] & (1 << ((groupOffset + j) & kFlagsMask))) == 0)
|
||||
break;
|
||||
j++;
|
||||
thereAreGroups = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return thereAreGroups;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* conditions: blockSize > 0 */
|
||||
UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
|
||||
{
|
||||
UInt32 *counters = Indices + blockSize;
|
||||
UInt32 i;
|
||||
UInt32 *Groups;
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
UInt32 *Flags;
|
||||
#endif
|
||||
|
||||
/* Radix-Sort for 2 bytes */
|
||||
for (i = 0; i < kNumHashValues; i++)
|
||||
counters[i] = 0;
|
||||
for (i = 0; i < blockSize - 1; i++)
|
||||
counters[((UInt32)data[i] << 8) | data[i + 1]]++;
|
||||
counters[((UInt32)data[i] << 8) | data[0]]++;
|
||||
|
||||
Groups = counters + BS_TEMP_SIZE;
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
Flags = Groups + blockSize;
|
||||
{
|
||||
UInt32 numWords = (blockSize + kFlagsMask) >> kNumFlagsBits;
|
||||
for (i = 0; i < numWords; i++)
|
||||
Flags[i] = kAllFlags;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
UInt32 sum = 0;
|
||||
for (i = 0; i < kNumHashValues; i++)
|
||||
{
|
||||
UInt32 groupSize = counters[i];
|
||||
if (groupSize > 0)
|
||||
{
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
UInt32 t = sum + groupSize - 1;
|
||||
Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask));
|
||||
#endif
|
||||
sum += groupSize;
|
||||
}
|
||||
counters[i] = sum - groupSize;
|
||||
}
|
||||
|
||||
for (i = 0; i < blockSize - 1; i++)
|
||||
Groups[i] = counters[((UInt32)data[i] << 8) | data[i + 1]];
|
||||
Groups[i] = counters[((UInt32)data[i] << 8) | data[0]];
|
||||
|
||||
for (i = 0; i < blockSize - 1; i++)
|
||||
Indices[counters[((UInt32)data[i] << 8) | data[i + 1]]++] = i;
|
||||
Indices[counters[((UInt32)data[i] << 8) | data[0]]++] = i;
|
||||
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
{
|
||||
UInt32 prev = 0;
|
||||
for (i = 0; i < kNumHashValues; i++)
|
||||
{
|
||||
UInt32 prevGroupSize = counters[i] - prev;
|
||||
if (prevGroupSize == 0)
|
||||
continue;
|
||||
SetGroupSize(Indices + prev, prevGroupSize);
|
||||
prev = counters[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
int NumRefBits;
|
||||
UInt32 NumSortedBytes;
|
||||
for (NumRefBits = 0; ((blockSize - 1) >> NumRefBits) != 0; NumRefBits++);
|
||||
NumRefBits = 32 - NumRefBits;
|
||||
if (NumRefBits > kNumRefBitsMax)
|
||||
NumRefBits = kNumRefBitsMax;
|
||||
|
||||
for (NumSortedBytes = kNumHashBytes; ; NumSortedBytes <<= 1)
|
||||
{
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
UInt32 finishedGroupSize = 0;
|
||||
#endif
|
||||
UInt32 newLimit = 0;
|
||||
for (i = 0; i < blockSize;)
|
||||
{
|
||||
UInt32 groupSize;
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
|
||||
if ((Flags[i >> kNumFlagsBits] & (1 << (i & kFlagsMask))) == 0)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
for (groupSize = 1;
|
||||
(Flags[(i + groupSize) >> kNumFlagsBits] & (1 << ((i + groupSize) & kFlagsMask))) != 0;
|
||||
groupSize++);
|
||||
|
||||
groupSize++;
|
||||
|
||||
#else
|
||||
|
||||
groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax);
|
||||
{
|
||||
Bool finishedGroup = ((Indices[i] & 0x80000000) == 0);
|
||||
if ((Indices[i] & 0x40000000) != 0)
|
||||
{
|
||||
groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits);
|
||||
Indices[i + 1] &= kIndexMask;
|
||||
}
|
||||
Indices[i] &= kIndexMask;
|
||||
groupSize++;
|
||||
if (finishedGroup || groupSize == 1)
|
||||
{
|
||||
Indices[i - finishedGroupSize] &= kIndexMask;
|
||||
if (finishedGroupSize > 1)
|
||||
Indices[i - finishedGroupSize + 1] &= kIndexMask;
|
||||
{
|
||||
UInt32 newGroupSize = groupSize + finishedGroupSize;
|
||||
SetFinishedGroupSize(Indices + i - finishedGroupSize, newGroupSize);
|
||||
finishedGroupSize = newGroupSize;
|
||||
}
|
||||
i += groupSize;
|
||||
continue;
|
||||
}
|
||||
finishedGroupSize = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (NumSortedBytes >= blockSize)
|
||||
{
|
||||
UInt32 j;
|
||||
for (j = 0; j < groupSize; j++)
|
||||
{
|
||||
UInt32 t = (i + j);
|
||||
/* Flags[t >> kNumFlagsBits] &= ~(1 << (t & kFlagsMask)); */
|
||||
Groups[Indices[t]] = t;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (SortGroup(blockSize, NumSortedBytes, i, groupSize, NumRefBits, Indices
|
||||
#ifndef BLOCK_SORT_USE_HEAP_SORT
|
||||
, 0, blockSize
|
||||
#endif
|
||||
) != 0)
|
||||
newLimit = i + groupSize;
|
||||
i += groupSize;
|
||||
}
|
||||
if (newLimit == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifndef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
for (i = 0; i < blockSize;)
|
||||
{
|
||||
UInt32 groupSize = ((Indices[i] & ~0xC0000000) >> kNumBitsMax);
|
||||
if ((Indices[i] & 0x40000000) != 0)
|
||||
{
|
||||
groupSize += ((Indices[i + 1] >> kNumBitsMax) << kNumExtra0Bits);
|
||||
Indices[i + 1] &= kIndexMask;
|
||||
}
|
||||
Indices[i] &= kIndexMask;
|
||||
groupSize++;
|
||||
i += groupSize;
|
||||
}
|
||||
#endif
|
||||
return Groups[0];
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
/* BwtSort.h -- BWT block sorting
|
||||
2008-03-26
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#ifndef __BWTSORT_H
|
||||
#define __BWTSORT_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
/* use BLOCK_SORT_EXTERNAL_FLAGS if blockSize can be > 1M */
|
||||
/* #define BLOCK_SORT_EXTERNAL_FLAGS */
|
||||
|
||||
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
|
||||
#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) ((((blockSize) + 31) >> 5))
|
||||
#else
|
||||
#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) 0
|
||||
#endif
|
||||
|
||||
#define BLOCK_SORT_BUF_SIZE(blockSize) ((blockSize) * 2 + BLOCK_SORT_EXTERNAL_SIZE(blockSize) + (1 << 16))
|
||||
|
||||
UInt32 BlockSort(UInt32 *indices, const Byte *data, UInt32 blockSize);
|
||||
|
||||
#endif
|
|
@ -1,69 +0,0 @@
|
|||
/* CpuArch.h
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#ifndef __CPUARCH_H
|
||||
#define __CPUARCH_H
|
||||
|
||||
/*
|
||||
LITTLE_ENDIAN_UNALIGN means:
|
||||
1) CPU is LITTLE_ENDIAN
|
||||
2) it's allowed to make unaligned memory accesses
|
||||
if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know
|
||||
about these properties of platform.
|
||||
*/
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__)
|
||||
#define LITTLE_ENDIAN_UNALIGN
|
||||
#endif
|
||||
|
||||
#ifdef LITTLE_ENDIAN_UNALIGN
|
||||
|
||||
#define GetUi16(p) (*(const UInt16 *)(p))
|
||||
#define GetUi32(p) (*(const UInt32 *)(p))
|
||||
#define GetUi64(p) (*(const UInt64 *)(p))
|
||||
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
|
||||
|
||||
#else
|
||||
|
||||
#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
|
||||
|
||||
#define GetUi32(p) ( \
|
||||
((const Byte *)(p))[0] | \
|
||||
((UInt32)((const Byte *)(p))[1] << 8) | \
|
||||
((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 SetUi32(p, d) { UInt32 _x_ = (d); \
|
||||
((Byte *)(p))[0] = (Byte)_x_; \
|
||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
|
||||
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
|
||||
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
|
||||
|
||||
#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
|
|
@ -1,148 +0,0 @@
|
|||
/* HuffEnc.c -- functions for Huffman encoding
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#include "HuffEnc.h"
|
||||
#include "Sort.h"
|
||||
|
||||
#define kMaxLen 16
|
||||
#define NUM_BITS 10
|
||||
#define MASK ((1 << NUM_BITS) - 1)
|
||||
|
||||
#define NUM_COUNTERS 64
|
||||
|
||||
#define HUFFMAN_SPEED_OPT
|
||||
|
||||
void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymbols, UInt32 maxLen)
|
||||
{
|
||||
UInt32 num = 0;
|
||||
/* if (maxLen > 10) maxLen = 10; */
|
||||
{
|
||||
UInt32 i;
|
||||
|
||||
#ifdef HUFFMAN_SPEED_OPT
|
||||
|
||||
UInt32 counters[NUM_COUNTERS];
|
||||
for (i = 0; i < NUM_COUNTERS; i++)
|
||||
counters[i] = 0;
|
||||
for (i = 0; i < numSymbols; i++)
|
||||
{
|
||||
UInt32 freq = freqs[i];
|
||||
counters[(freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1]++;
|
||||
}
|
||||
|
||||
for (i = 1; i < NUM_COUNTERS; i++)
|
||||
{
|
||||
UInt32 temp = counters[i];
|
||||
counters[i] = num;
|
||||
num += temp;
|
||||
}
|
||||
|
||||
for (i = 0; i < numSymbols; i++)
|
||||
{
|
||||
UInt32 freq = freqs[i];
|
||||
if (freq == 0)
|
||||
lens[i] = 0;
|
||||
else
|
||||
p[counters[((freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1)]++] = i | (freq << NUM_BITS);
|
||||
}
|
||||
counters[0] = 0;
|
||||
HeapSort(p + counters[NUM_COUNTERS - 2], counters[NUM_COUNTERS - 1] - counters[NUM_COUNTERS - 2]);
|
||||
|
||||
#else
|
||||
|
||||
for (i = 0; i < numSymbols; i++)
|
||||
{
|
||||
UInt32 freq = freqs[i];
|
||||
if (freq == 0)
|
||||
lens[i] = 0;
|
||||
else
|
||||
p[num++] = i | (freq << NUM_BITS);
|
||||
}
|
||||
HeapSort(p, num);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
if (num < 2)
|
||||
{
|
||||
int minCode = 0;
|
||||
int maxCode = 1;
|
||||
if (num == 1)
|
||||
{
|
||||
maxCode = (int)(p[0] & MASK);
|
||||
if (maxCode == 0)
|
||||
maxCode++;
|
||||
}
|
||||
p[minCode] = 0;
|
||||
p[maxCode] = 1;
|
||||
lens[minCode] = lens[maxCode] = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
UInt32 b, e, i;
|
||||
|
||||
i = b = e = 0;
|
||||
do
|
||||
{
|
||||
UInt32 n, m, freq;
|
||||
n = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++;
|
||||
freq = (p[n] & ~MASK);
|
||||
p[n] = (p[n] & MASK) | (e << NUM_BITS);
|
||||
m = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++;
|
||||
freq += (p[m] & ~MASK);
|
||||
p[m] = (p[m] & MASK) | (e << NUM_BITS);
|
||||
p[e] = (p[e] & MASK) | freq;
|
||||
e++;
|
||||
}
|
||||
while (num - e > 1);
|
||||
|
||||
{
|
||||
UInt32 lenCounters[kMaxLen + 1];
|
||||
for (i = 0; i <= kMaxLen; i++)
|
||||
lenCounters[i] = 0;
|
||||
|
||||
p[--e] &= MASK;
|
||||
lenCounters[1] = 2;
|
||||
while (e > 0)
|
||||
{
|
||||
UInt32 len = (p[p[--e] >> NUM_BITS] >> NUM_BITS) + 1;
|
||||
p[e] = (p[e] & MASK) | (len << NUM_BITS);
|
||||
if (len >= maxLen)
|
||||
for (len = maxLen - 1; lenCounters[len] == 0; len--);
|
||||
lenCounters[len]--;
|
||||
lenCounters[len + 1] += 2;
|
||||
}
|
||||
|
||||
{
|
||||
UInt32 len;
|
||||
i = 0;
|
||||
for (len = maxLen; len != 0; len--)
|
||||
{
|
||||
UInt32 num;
|
||||
for (num = lenCounters[len]; num != 0; num--)
|
||||
lens[p[i++] & MASK] = (Byte)len;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
UInt32 nextCodes[kMaxLen + 1];
|
||||
{
|
||||
UInt32 code = 0;
|
||||
UInt32 len;
|
||||
for (len = 1; len <= kMaxLen; len++)
|
||||
nextCodes[len] = code = (code + lenCounters[len - 1]) << 1;
|
||||
}
|
||||
/* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */
|
||||
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < numSymbols; i++)
|
||||
p[i] = nextCodes[lens[i]]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
/* HuffEnc.h -- functions for Huffman encoding
|
||||
2008-03-26
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#ifndef __HUFFENC_H
|
||||
#define __HUFFENC_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
/*
|
||||
Conditions:
|
||||
num <= 1024 = 2 ^ NUM_BITS
|
||||
Sum(freqs) < 4M = 2 ^ (32 - NUM_BITS)
|
||||
maxLen <= 16 = kMaxLen
|
||||
Num_Items(p) >= HUFFMAN_TEMP_SIZE(num)
|
||||
*/
|
||||
|
||||
void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 num, UInt32 maxLen);
|
||||
|
||||
#endif
|
|
@ -1,751 +0,0 @@
|
|||
/* LzFind.c -- Match finder for LZ algorithms
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "LzFind.h"
|
||||
#include "LzHash.h"
|
||||
|
||||
#define kEmptyHashValue 0
|
||||
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
|
||||
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
|
||||
#define kNormalizeMask (~(kNormalizeStepMin - 1))
|
||||
#define kMaxHistorySize ((UInt32)3 << 30)
|
||||
|
||||
#define kStartMaxLen 3
|
||||
|
||||
static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
|
||||
{
|
||||
if (!p->directInput)
|
||||
{
|
||||
alloc->Free(alloc, p->bufferBase);
|
||||
p->bufferBase = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
|
||||
|
||||
static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
|
||||
{
|
||||
UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
|
||||
if (p->directInput)
|
||||
{
|
||||
p->blockSize = blockSize;
|
||||
return 1;
|
||||
}
|
||||
if (p->bufferBase == 0 || p->blockSize != blockSize)
|
||||
{
|
||||
LzInWindow_Free(p, alloc);
|
||||
p->blockSize = blockSize;
|
||||
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
|
||||
}
|
||||
return (p->bufferBase != 0);
|
||||
}
|
||||
|
||||
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
|
||||
Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
|
||||
|
||||
UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
|
||||
|
||||
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
|
||||
{
|
||||
p->posLimit -= subValue;
|
||||
p->pos -= subValue;
|
||||
p->streamPos -= subValue;
|
||||
}
|
||||
|
||||
static void MatchFinder_ReadBlock(CMatchFinder *p)
|
||||
{
|
||||
if (p->streamEndWasReached || p->result != SZ_OK)
|
||||
return;
|
||||
for (;;)
|
||||
{
|
||||
Byte *dest = p->buffer + (p->streamPos - p->pos);
|
||||
size_t size = (p->bufferBase + p->blockSize - dest);
|
||||
if (size == 0)
|
||||
return;
|
||||
p->result = p->stream->Read(p->stream, dest, &size);
|
||||
if (p->result != SZ_OK)
|
||||
return;
|
||||
if (size == 0)
|
||||
{
|
||||
p->streamEndWasReached = 1;
|
||||
return;
|
||||
}
|
||||
p->streamPos += (UInt32)size;
|
||||
if (p->streamPos - p->pos > p->keepSizeAfter)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void MatchFinder_MoveBlock(CMatchFinder *p)
|
||||
{
|
||||
memmove(p->bufferBase,
|
||||
p->buffer - p->keepSizeBefore,
|
||||
(size_t)(p->streamPos - p->pos + p->keepSizeBefore));
|
||||
p->buffer = p->bufferBase + p->keepSizeBefore;
|
||||
}
|
||||
|
||||
int MatchFinder_NeedMove(CMatchFinder *p)
|
||||
{
|
||||
/* if (p->streamEndWasReached) return 0; */
|
||||
return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
|
||||
}
|
||||
|
||||
void MatchFinder_ReadIfRequired(CMatchFinder *p)
|
||||
{
|
||||
if (p->streamEndWasReached)
|
||||
return;
|
||||
if (p->keepSizeAfter >= p->streamPos - p->pos)
|
||||
MatchFinder_ReadBlock(p);
|
||||
}
|
||||
|
||||
static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
|
||||
{
|
||||
if (MatchFinder_NeedMove(p))
|
||||
MatchFinder_MoveBlock(p);
|
||||
MatchFinder_ReadBlock(p);
|
||||
}
|
||||
|
||||
static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
|
||||
{
|
||||
p->cutValue = 32;
|
||||
p->btMode = 1;
|
||||
p->numHashBytes = 4;
|
||||
/* p->skipModeBits = 0; */
|
||||
p->directInput = 0;
|
||||
p->bigHash = 0;
|
||||
}
|
||||
|
||||
#define kCrcPoly 0xEDB88320
|
||||
|
||||
void MatchFinder_Construct(CMatchFinder *p)
|
||||
{
|
||||
UInt32 i;
|
||||
p->bufferBase = 0;
|
||||
p->directInput = 0;
|
||||
p->hash = 0;
|
||||
MatchFinder_SetDefaultSettings(p);
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
UInt32 r = i;
|
||||
int j;
|
||||
for (j = 0; j < 8; j++)
|
||||
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
||||
p->crc[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
|
||||
{
|
||||
alloc->Free(alloc, p->hash);
|
||||
p->hash = 0;
|
||||
}
|
||||
|
||||
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
|
||||
{
|
||||
MatchFinder_FreeThisClassMemory(p, alloc);
|
||||
LzInWindow_Free(p, alloc);
|
||||
}
|
||||
|
||||
static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
|
||||
{
|
||||
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
|
||||
if (sizeInBytes / sizeof(CLzRef) != num)
|
||||
return 0;
|
||||
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
|
||||
}
|
||||
|
||||
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||
ISzAlloc *alloc)
|
||||
{
|
||||
UInt32 sizeReserv;
|
||||
if (historySize > kMaxHistorySize)
|
||||
{
|
||||
MatchFinder_Free(p, alloc);
|
||||
return 0;
|
||||
}
|
||||
sizeReserv = historySize >> 1;
|
||||
if (historySize > ((UInt32)2 << 30))
|
||||
sizeReserv = historySize >> 2;
|
||||
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
|
||||
|
||||
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
|
||||
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
|
||||
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
|
||||
if (LzInWindow_Create(p, sizeReserv, alloc))
|
||||
{
|
||||
UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1;
|
||||
UInt32 hs;
|
||||
p->matchMaxLen = matchMaxLen;
|
||||
{
|
||||
p->fixedHashSize = 0;
|
||||
if (p->numHashBytes == 2)
|
||||
hs = (1 << 16) - 1;
|
||||
else
|
||||
{
|
||||
hs = historySize - 1;
|
||||
hs |= (hs >> 1);
|
||||
hs |= (hs >> 2);
|
||||
hs |= (hs >> 4);
|
||||
hs |= (hs >> 8);
|
||||
hs >>= 1;
|
||||
/* hs >>= p->skipModeBits; */
|
||||
hs |= 0xFFFF; /* don't change it! It's required for Deflate */
|
||||
if (hs > (1 << 24))
|
||||
{
|
||||
if (p->numHashBytes == 3)
|
||||
hs = (1 << 24) - 1;
|
||||
else
|
||||
hs >>= 1;
|
||||
}
|
||||
}
|
||||
p->hashMask = hs;
|
||||
hs++;
|
||||
if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
|
||||
if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
|
||||
if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
|
||||
hs += p->fixedHashSize;
|
||||
}
|
||||
|
||||
{
|
||||
UInt32 prevSize = p->hashSizeSum + p->numSons;
|
||||
UInt32 newSize;
|
||||
p->historySize = historySize;
|
||||
p->hashSizeSum = hs;
|
||||
p->cyclicBufferSize = newCyclicBufferSize;
|
||||
p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
|
||||
newSize = p->hashSizeSum + p->numSons;
|
||||
if (p->hash != 0 && prevSize == newSize)
|
||||
return 1;
|
||||
MatchFinder_FreeThisClassMemory(p, alloc);
|
||||
p->hash = AllocRefs(newSize, alloc);
|
||||
if (p->hash != 0)
|
||||
{
|
||||
p->son = p->hash + p->hashSizeSum;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
MatchFinder_Free(p, alloc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void MatchFinder_SetLimits(CMatchFinder *p)
|
||||
{
|
||||
UInt32 limit = kMaxValForNormalize - p->pos;
|
||||
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
|
||||
if (limit2 < limit)
|
||||
limit = limit2;
|
||||
limit2 = p->streamPos - p->pos;
|
||||
if (limit2 <= p->keepSizeAfter)
|
||||
{
|
||||
if (limit2 > 0)
|
||||
limit2 = 1;
|
||||
}
|
||||
else
|
||||
limit2 -= p->keepSizeAfter;
|
||||
if (limit2 < limit)
|
||||
limit = limit2;
|
||||
{
|
||||
UInt32 lenLimit = p->streamPos - p->pos;
|
||||
if (lenLimit > p->matchMaxLen)
|
||||
lenLimit = p->matchMaxLen;
|
||||
p->lenLimit = lenLimit;
|
||||
}
|
||||
p->posLimit = p->pos + limit;
|
||||
}
|
||||
|
||||
void MatchFinder_Init(CMatchFinder *p)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < p->hashSizeSum; i++)
|
||||
p->hash[i] = kEmptyHashValue;
|
||||
p->cyclicBufferPos = 0;
|
||||
p->buffer = p->bufferBase;
|
||||
p->pos = p->streamPos = p->cyclicBufferSize;
|
||||
p->result = SZ_OK;
|
||||
p->streamEndWasReached = 0;
|
||||
MatchFinder_ReadBlock(p);
|
||||
MatchFinder_SetLimits(p);
|
||||
}
|
||||
|
||||
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
|
||||
{
|
||||
return (p->pos - p->historySize - 1) & kNormalizeMask;
|
||||
}
|
||||
|
||||
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 value = items[i];
|
||||
if (value <= subValue)
|
||||
value = kEmptyHashValue;
|
||||
else
|
||||
value -= subValue;
|
||||
items[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
static void MatchFinder_Normalize(CMatchFinder *p)
|
||||
{
|
||||
UInt32 subValue = MatchFinder_GetSubValue(p);
|
||||
MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
|
||||
MatchFinder_ReduceOffsets(p, subValue);
|
||||
}
|
||||
|
||||
static void MatchFinder_CheckLimits(CMatchFinder *p)
|
||||
{
|
||||
if (p->pos == kMaxValForNormalize)
|
||||
MatchFinder_Normalize(p);
|
||||
if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
|
||||
MatchFinder_CheckAndMoveAndRead(p);
|
||||
if (p->cyclicBufferPos == p->cyclicBufferSize)
|
||||
p->cyclicBufferPos = 0;
|
||||
MatchFinder_SetLimits(p);
|
||||
}
|
||||
|
||||
static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
||||
UInt32 *distances, UInt32 maxLen)
|
||||
{
|
||||
son[_cyclicBufferPos] = curMatch;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 delta = pos - curMatch;
|
||||
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||
return distances;
|
||||
{
|
||||
const Byte *pb = cur - delta;
|
||||
curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
|
||||
if (pb[maxLen] == cur[maxLen] && *pb == *cur)
|
||||
{
|
||||
UInt32 len = 0;
|
||||
while (++len != lenLimit)
|
||||
if (pb[len] != cur[len])
|
||||
break;
|
||||
if (maxLen < len)
|
||||
{
|
||||
*distances++ = maxLen = len;
|
||||
*distances++ = delta - 1;
|
||||
if (len == lenLimit)
|
||||
return distances;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
||||
UInt32 *distances, UInt32 maxLen)
|
||||
{
|
||||
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
|
||||
UInt32 len0 = 0, len1 = 0;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 delta = pos - curMatch;
|
||||
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||
{
|
||||
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||
return distances;
|
||||
}
|
||||
{
|
||||
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||
const Byte *pb = cur - delta;
|
||||
UInt32 len = (len0 < len1 ? len0 : len1);
|
||||
if (pb[len] == cur[len])
|
||||
{
|
||||
if (++len != lenLimit && pb[len] == cur[len])
|
||||
while (++len != lenLimit)
|
||||
if (pb[len] != cur[len])
|
||||
break;
|
||||
if (maxLen < len)
|
||||
{
|
||||
*distances++ = maxLen = len;
|
||||
*distances++ = delta - 1;
|
||||
if (len == lenLimit)
|
||||
{
|
||||
*ptr1 = pair[0];
|
||||
*ptr0 = pair[1];
|
||||
return distances;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pb[len] < cur[len])
|
||||
{
|
||||
*ptr1 = curMatch;
|
||||
ptr1 = pair + 1;
|
||||
curMatch = *ptr1;
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr0 = curMatch;
|
||||
ptr0 = pair;
|
||||
curMatch = *ptr0;
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
|
||||
{
|
||||
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
|
||||
UInt32 len0 = 0, len1 = 0;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 delta = pos - curMatch;
|
||||
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||
{
|
||||
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||
return;
|
||||
}
|
||||
{
|
||||
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||
const Byte *pb = cur - delta;
|
||||
UInt32 len = (len0 < len1 ? len0 : len1);
|
||||
if (pb[len] == cur[len])
|
||||
{
|
||||
while (++len != lenLimit)
|
||||
if (pb[len] != cur[len])
|
||||
break;
|
||||
{
|
||||
if (len == lenLimit)
|
||||
{
|
||||
*ptr1 = pair[0];
|
||||
*ptr0 = pair[1];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pb[len] < cur[len])
|
||||
{
|
||||
*ptr1 = curMatch;
|
||||
ptr1 = pair + 1;
|
||||
curMatch = *ptr1;
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr0 = curMatch;
|
||||
ptr0 = pair;
|
||||
curMatch = *ptr0;
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define MOVE_POS \
|
||||
++p->cyclicBufferPos; \
|
||||
p->buffer++; \
|
||||
if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
|
||||
|
||||
#define MOVE_POS_RET MOVE_POS return offset;
|
||||
|
||||
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
|
||||
|
||||
#define GET_MATCHES_HEADER2(minLen, ret_op) \
|
||||
UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
|
||||
lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
|
||||
cur = p->buffer;
|
||||
|
||||
#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
|
||||
#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
|
||||
|
||||
#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
|
||||
|
||||
#define GET_MATCHES_FOOTER(offset, maxLen) \
|
||||
offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
|
||||
distances + offset, maxLen) - distances); MOVE_POS_RET;
|
||||
|
||||
#define SKIP_FOOTER \
|
||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
|
||||
|
||||
static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 offset;
|
||||
GET_MATCHES_HEADER(2)
|
||||
HASH2_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
offset = 0;
|
||||
GET_MATCHES_FOOTER(offset, 1)
|
||||
}
|
||||
|
||||
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 offset;
|
||||
GET_MATCHES_HEADER(3)
|
||||
HASH_ZIP_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
offset = 0;
|
||||
GET_MATCHES_FOOTER(offset, 2)
|
||||
}
|
||||
|
||||
static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 hash2Value, delta2, maxLen, offset;
|
||||
GET_MATCHES_HEADER(3)
|
||||
|
||||
HASH3_CALC;
|
||||
|
||||
delta2 = p->pos - p->hash[hash2Value];
|
||||
curMatch = p->hash[kFix3HashSize + hashValue];
|
||||
|
||||
p->hash[hash2Value] =
|
||||
p->hash[kFix3HashSize + hashValue] = p->pos;
|
||||
|
||||
|
||||
maxLen = 2;
|
||||
offset = 0;
|
||||
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
||||
{
|
||||
for (; maxLen != lenLimit; maxLen++)
|
||||
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
||||
break;
|
||||
distances[0] = maxLen;
|
||||
distances[1] = delta2 - 1;
|
||||
offset = 2;
|
||||
if (maxLen == lenLimit)
|
||||
{
|
||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
||||
MOVE_POS_RET;
|
||||
}
|
||||
}
|
||||
GET_MATCHES_FOOTER(offset, maxLen)
|
||||
}
|
||||
|
||||
static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
|
||||
GET_MATCHES_HEADER(4)
|
||||
|
||||
HASH4_CALC;
|
||||
|
||||
delta2 = p->pos - p->hash[ hash2Value];
|
||||
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
|
||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||
|
||||
p->hash[ hash2Value] =
|
||||
p->hash[kFix3HashSize + hash3Value] =
|
||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||
|
||||
maxLen = 1;
|
||||
offset = 0;
|
||||
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
||||
{
|
||||
distances[0] = maxLen = 2;
|
||||
distances[1] = delta2 - 1;
|
||||
offset = 2;
|
||||
}
|
||||
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
|
||||
{
|
||||
maxLen = 3;
|
||||
distances[offset + 1] = delta3 - 1;
|
||||
offset += 2;
|
||||
delta2 = delta3;
|
||||
}
|
||||
if (offset != 0)
|
||||
{
|
||||
for (; maxLen != lenLimit; maxLen++)
|
||||
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
||||
break;
|
||||
distances[offset - 2] = maxLen;
|
||||
if (maxLen == lenLimit)
|
||||
{
|
||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
||||
MOVE_POS_RET;
|
||||
}
|
||||
}
|
||||
if (maxLen < 3)
|
||||
maxLen = 3;
|
||||
GET_MATCHES_FOOTER(offset, maxLen)
|
||||
}
|
||||
|
||||
static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
|
||||
GET_MATCHES_HEADER(4)
|
||||
|
||||
HASH4_CALC;
|
||||
|
||||
delta2 = p->pos - p->hash[ hash2Value];
|
||||
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
|
||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||
|
||||
p->hash[ hash2Value] =
|
||||
p->hash[kFix3HashSize + hash3Value] =
|
||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||
|
||||
maxLen = 1;
|
||||
offset = 0;
|
||||
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
||||
{
|
||||
distances[0] = maxLen = 2;
|
||||
distances[1] = delta2 - 1;
|
||||
offset = 2;
|
||||
}
|
||||
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
|
||||
{
|
||||
maxLen = 3;
|
||||
distances[offset + 1] = delta3 - 1;
|
||||
offset += 2;
|
||||
delta2 = delta3;
|
||||
}
|
||||
if (offset != 0)
|
||||
{
|
||||
for (; maxLen != lenLimit; maxLen++)
|
||||
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
||||
break;
|
||||
distances[offset - 2] = maxLen;
|
||||
if (maxLen == lenLimit)
|
||||
{
|
||||
p->son[p->cyclicBufferPos] = curMatch;
|
||||
MOVE_POS_RET;
|
||||
}
|
||||
}
|
||||
if (maxLen < 3)
|
||||
maxLen = 3;
|
||||
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||
distances + offset, maxLen) - (distances));
|
||||
MOVE_POS_RET
|
||||
}
|
||||
|
||||
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 offset;
|
||||
GET_MATCHES_HEADER(3)
|
||||
HASH_ZIP_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||
distances, 2) - (distances));
|
||||
MOVE_POS_RET
|
||||
}
|
||||
|
||||
static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
SKIP_HEADER(2)
|
||||
HASH2_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
SKIP_FOOTER
|
||||
}
|
||||
while (--num != 0);
|
||||
}
|
||||
|
||||
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
SKIP_HEADER(3)
|
||||
HASH_ZIP_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
SKIP_FOOTER
|
||||
}
|
||||
while (--num != 0);
|
||||
}
|
||||
|
||||
static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 hash2Value;
|
||||
SKIP_HEADER(3)
|
||||
HASH3_CALC;
|
||||
curMatch = p->hash[kFix3HashSize + hashValue];
|
||||
p->hash[hash2Value] =
|
||||
p->hash[kFix3HashSize + hashValue] = p->pos;
|
||||
SKIP_FOOTER
|
||||
}
|
||||
while (--num != 0);
|
||||
}
|
||||
|
||||
static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 hash2Value, hash3Value;
|
||||
SKIP_HEADER(4)
|
||||
HASH4_CALC;
|
||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||
p->hash[ hash2Value] =
|
||||
p->hash[kFix3HashSize + hash3Value] = p->pos;
|
||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||
SKIP_FOOTER
|
||||
}
|
||||
while (--num != 0);
|
||||
}
|
||||
|
||||
static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 hash2Value, hash3Value;
|
||||
SKIP_HEADER(4)
|
||||
HASH4_CALC;
|
||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||
p->hash[ hash2Value] =
|
||||
p->hash[kFix3HashSize + hash3Value] =
|
||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||
p->son[p->cyclicBufferPos] = curMatch;
|
||||
MOVE_POS
|
||||
}
|
||||
while (--num != 0);
|
||||
}
|
||||
|
||||
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
SKIP_HEADER(3)
|
||||
HASH_ZIP_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
p->son[p->cyclicBufferPos] = curMatch;
|
||||
MOVE_POS
|
||||
}
|
||||
while (--num != 0);
|
||||
}
|
||||
|
||||
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
|
||||
{
|
||||
vTable->Init = (Mf_Init_Func)MatchFinder_Init;
|
||||
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
|
||||
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
|
||||
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
|
||||
if (!p->btMode)
|
||||
{
|
||||
vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
|
||||
vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
|
||||
}
|
||||
else if (p->numHashBytes == 2)
|
||||
{
|
||||
vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
|
||||
vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
|
||||
}
|
||||
else if (p->numHashBytes == 3)
|
||||
{
|
||||
vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
|
||||
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
|
||||
}
|
||||
else
|
||||
{
|
||||
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
|
||||
vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
|
||||
}
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
/* LzFind.h -- Match finder for LZ algorithms
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZFIND_H
|
||||
#define __LZFIND_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
typedef UInt32 CLzRef;
|
||||
|
||||
typedef struct _CMatchFinder
|
||||
{
|
||||
Byte *buffer;
|
||||
UInt32 pos;
|
||||
UInt32 posLimit;
|
||||
UInt32 streamPos;
|
||||
UInt32 lenLimit;
|
||||
|
||||
UInt32 cyclicBufferPos;
|
||||
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
|
||||
|
||||
UInt32 matchMaxLen;
|
||||
CLzRef *hash;
|
||||
CLzRef *son;
|
||||
UInt32 hashMask;
|
||||
UInt32 cutValue;
|
||||
|
||||
Byte *bufferBase;
|
||||
ISeqInStream *stream;
|
||||
int streamEndWasReached;
|
||||
|
||||
UInt32 blockSize;
|
||||
UInt32 keepSizeBefore;
|
||||
UInt32 keepSizeAfter;
|
||||
|
||||
UInt32 numHashBytes;
|
||||
int directInput;
|
||||
int btMode;
|
||||
/* int skipModeBits; */
|
||||
int bigHash;
|
||||
UInt32 historySize;
|
||||
UInt32 fixedHashSize;
|
||||
UInt32 hashSizeSum;
|
||||
UInt32 numSons;
|
||||
SRes result;
|
||||
UInt32 crc[256];
|
||||
} CMatchFinder;
|
||||
|
||||
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
|
||||
#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
|
||||
|
||||
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
|
||||
|
||||
int MatchFinder_NeedMove(CMatchFinder *p);
|
||||
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
|
||||
void MatchFinder_MoveBlock(CMatchFinder *p);
|
||||
void MatchFinder_ReadIfRequired(CMatchFinder *p);
|
||||
|
||||
void MatchFinder_Construct(CMatchFinder *p);
|
||||
|
||||
/* Conditions:
|
||||
historySize <= 3 GB
|
||||
keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
|
||||
*/
|
||||
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||
ISzAlloc *alloc);
|
||||
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
|
||||
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
|
||||
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
|
||||
|
||||
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
||||
UInt32 *distances, UInt32 maxLen);
|
||||
|
||||
/*
|
||||
Conditions:
|
||||
Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
|
||||
Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
|
||||
*/
|
||||
|
||||
typedef void (*Mf_Init_Func)(void *object);
|
||||
typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
|
||||
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
|
||||
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
|
||||
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
|
||||
typedef void (*Mf_Skip_Func)(void *object, UInt32);
|
||||
|
||||
typedef struct _IMatchFinder
|
||||
{
|
||||
Mf_Init_Func Init;
|
||||
Mf_GetIndexByte_Func GetIndexByte;
|
||||
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
|
||||
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
|
||||
Mf_GetMatches_Func GetMatches;
|
||||
Mf_Skip_Func Skip;
|
||||
} IMatchFinder;
|
||||
|
||||
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
|
||||
|
||||
void MatchFinder_Init(CMatchFinder *p);
|
||||
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||
|
||||
#endif
|
|
@ -1,793 +0,0 @@
|
|||
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "LzHash.h"
|
||||
|
||||
#include "LzFindMt.h"
|
||||
|
||||
void MtSync_Construct(CMtSync *p)
|
||||
{
|
||||
p->wasCreated = False;
|
||||
p->csWasInitialized = False;
|
||||
p->csWasEntered = False;
|
||||
Thread_Construct(&p->thread);
|
||||
Event_Construct(&p->canStart);
|
||||
Event_Construct(&p->wasStarted);
|
||||
Event_Construct(&p->wasStopped);
|
||||
Semaphore_Construct(&p->freeSemaphore);
|
||||
Semaphore_Construct(&p->filledSemaphore);
|
||||
}
|
||||
|
||||
void MtSync_GetNextBlock(CMtSync *p)
|
||||
{
|
||||
if (p->needStart)
|
||||
{
|
||||
p->numProcessedBlocks = 1;
|
||||
p->needStart = False;
|
||||
p->stopWriting = False;
|
||||
p->exit = False;
|
||||
Event_Reset(&p->wasStarted);
|
||||
Event_Reset(&p->wasStopped);
|
||||
|
||||
Event_Set(&p->canStart);
|
||||
Event_Wait(&p->wasStarted);
|
||||
}
|
||||
else
|
||||
{
|
||||
CriticalSection_Leave(&p->cs);
|
||||
p->csWasEntered = False;
|
||||
p->numProcessedBlocks++;
|
||||
Semaphore_Release1(&p->freeSemaphore);
|
||||
}
|
||||
Semaphore_Wait(&p->filledSemaphore);
|
||||
CriticalSection_Enter(&p->cs);
|
||||
p->csWasEntered = True;
|
||||
}
|
||||
|
||||
/* MtSync_StopWriting must be called if Writing was started */
|
||||
|
||||
void MtSync_StopWriting(CMtSync *p)
|
||||
{
|
||||
UInt32 myNumBlocks = p->numProcessedBlocks;
|
||||
if (!Thread_WasCreated(&p->thread) || p->needStart)
|
||||
return;
|
||||
p->stopWriting = True;
|
||||
if (p->csWasEntered)
|
||||
{
|
||||
CriticalSection_Leave(&p->cs);
|
||||
p->csWasEntered = False;
|
||||
}
|
||||
Semaphore_Release1(&p->freeSemaphore);
|
||||
|
||||
Event_Wait(&p->wasStopped);
|
||||
|
||||
while (myNumBlocks++ != p->numProcessedBlocks)
|
||||
{
|
||||
Semaphore_Wait(&p->filledSemaphore);
|
||||
Semaphore_Release1(&p->freeSemaphore);
|
||||
}
|
||||
p->needStart = True;
|
||||
}
|
||||
|
||||
void MtSync_Destruct(CMtSync *p)
|
||||
{
|
||||
if (Thread_WasCreated(&p->thread))
|
||||
{
|
||||
MtSync_StopWriting(p);
|
||||
p->exit = True;
|
||||
if (p->needStart)
|
||||
Event_Set(&p->canStart);
|
||||
Thread_Wait(&p->thread);
|
||||
Thread_Close(&p->thread);
|
||||
}
|
||||
if (p->csWasInitialized)
|
||||
{
|
||||
CriticalSection_Delete(&p->cs);
|
||||
p->csWasInitialized = False;
|
||||
}
|
||||
|
||||
Event_Close(&p->canStart);
|
||||
Event_Close(&p->wasStarted);
|
||||
Event_Close(&p->wasStopped);
|
||||
Semaphore_Close(&p->freeSemaphore);
|
||||
Semaphore_Close(&p->filledSemaphore);
|
||||
|
||||
p->wasCreated = False;
|
||||
}
|
||||
|
||||
#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
|
||||
|
||||
static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
|
||||
{
|
||||
if (p->wasCreated)
|
||||
return SZ_OK;
|
||||
|
||||
RINOK_THREAD(CriticalSection_Init(&p->cs));
|
||||
p->csWasInitialized = True;
|
||||
|
||||
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart));
|
||||
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStarted));
|
||||
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped));
|
||||
|
||||
RINOK_THREAD(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks));
|
||||
RINOK_THREAD(Semaphore_Create(&p->filledSemaphore, 0, numBlocks));
|
||||
|
||||
p->needStart = True;
|
||||
|
||||
RINOK_THREAD(Thread_Create(&p->thread, startAddress, obj));
|
||||
p->wasCreated = True;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static SRes MtSync_Create(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
|
||||
{
|
||||
SRes res = MtSync_Create2(p, startAddress, obj, numBlocks);
|
||||
if (res != SZ_OK)
|
||||
MtSync_Destruct(p);
|
||||
return res;
|
||||
}
|
||||
|
||||
void MtSync_Init(CMtSync *p) { p->needStart = True; }
|
||||
|
||||
#define kMtMaxValForNormalize 0xFFFFFFFF
|
||||
|
||||
#define DEF_GetHeads2(name, v, action) \
|
||||
static void GetHeads ## name(const Byte *p, UInt32 pos, \
|
||||
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
|
||||
{ action; for (; numHeads != 0; numHeads--) { \
|
||||
const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
|
||||
|
||||
#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;)
|
||||
|
||||
DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; )
|
||||
DEF_GetHeads(3, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
|
||||
DEF_GetHeads(4, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask)
|
||||
DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)
|
||||
DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask)
|
||||
|
||||
void HashThreadFunc(CMatchFinderMt *mt)
|
||||
{
|
||||
CMtSync *p = &mt->hashSync;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 numProcessedBlocks = 0;
|
||||
Event_Wait(&p->canStart);
|
||||
Event_Set(&p->wasStarted);
|
||||
for (;;)
|
||||
{
|
||||
if (p->exit)
|
||||
return;
|
||||
if (p->stopWriting)
|
||||
{
|
||||
p->numProcessedBlocks = numProcessedBlocks;
|
||||
Event_Set(&p->wasStopped);
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
CMatchFinder *mf = mt->MatchFinder;
|
||||
if (MatchFinder_NeedMove(mf))
|
||||
{
|
||||
CriticalSection_Enter(&mt->btSync.cs);
|
||||
CriticalSection_Enter(&mt->hashSync.cs);
|
||||
{
|
||||
const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf);
|
||||
const Byte *afterPtr;
|
||||
MatchFinder_MoveBlock(mf);
|
||||
afterPtr = MatchFinder_GetPointerToCurrentPos(mf);
|
||||
mt->pointerToCurPos -= beforePtr - afterPtr;
|
||||
mt->buffer -= beforePtr - afterPtr;
|
||||
}
|
||||
CriticalSection_Leave(&mt->btSync.cs);
|
||||
CriticalSection_Leave(&mt->hashSync.cs);
|
||||
continue;
|
||||
}
|
||||
|
||||
Semaphore_Wait(&p->freeSemaphore);
|
||||
|
||||
MatchFinder_ReadIfRequired(mf);
|
||||
if (mf->pos > (kMtMaxValForNormalize - kMtHashBlockSize))
|
||||
{
|
||||
UInt32 subValue = (mf->pos - mf->historySize - 1);
|
||||
MatchFinder_ReduceOffsets(mf, subValue);
|
||||
MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, mf->hashMask + 1);
|
||||
}
|
||||
{
|
||||
UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize;
|
||||
UInt32 num = mf->streamPos - mf->pos;
|
||||
heads[0] = 2;
|
||||
heads[1] = num;
|
||||
if (num >= mf->numHashBytes)
|
||||
{
|
||||
num = num - mf->numHashBytes + 1;
|
||||
if (num > kMtHashBlockSize - 2)
|
||||
num = kMtHashBlockSize - 2;
|
||||
mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc);
|
||||
heads[0] += num;
|
||||
}
|
||||
mf->pos += num;
|
||||
mf->buffer += num;
|
||||
}
|
||||
}
|
||||
|
||||
Semaphore_Release1(&p->filledSemaphore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
|
||||
{
|
||||
MtSync_GetNextBlock(&p->hashSync);
|
||||
p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize;
|
||||
p->hashBufPosLimit += p->hashBuf[p->hashBufPos++];
|
||||
p->hashNumAvail = p->hashBuf[p->hashBufPos++];
|
||||
}
|
||||
|
||||
#define kEmptyHashValue 0
|
||||
|
||||
/* #define MFMT_GM_INLINE */
|
||||
|
||||
#ifdef MFMT_GM_INLINE
|
||||
|
||||
#define NO_INLINE MY_FAST_CALL
|
||||
|
||||
Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
||||
UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 *distances = _distances + 1;
|
||||
UInt32 curMatch = pos - *hash++;
|
||||
|
||||
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
|
||||
UInt32 len0 = 0, len1 = 0;
|
||||
UInt32 cutValue = _cutValue;
|
||||
UInt32 maxLen = _maxLen;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 delta = pos - curMatch;
|
||||
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||
{
|
||||
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||
break;
|
||||
}
|
||||
{
|
||||
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||
const Byte *pb = cur - delta;
|
||||
UInt32 len = (len0 < len1 ? len0 : len1);
|
||||
if (pb[len] == cur[len])
|
||||
{
|
||||
if (++len != lenLimit && pb[len] == cur[len])
|
||||
while (++len != lenLimit)
|
||||
if (pb[len] != cur[len])
|
||||
break;
|
||||
if (maxLen < len)
|
||||
{
|
||||
*distances++ = maxLen = len;
|
||||
*distances++ = delta - 1;
|
||||
if (len == lenLimit)
|
||||
{
|
||||
*ptr1 = pair[0];
|
||||
*ptr0 = pair[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pb[len] < cur[len])
|
||||
{
|
||||
*ptr1 = curMatch;
|
||||
ptr1 = pair + 1;
|
||||
curMatch = *ptr1;
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr0 = curMatch;
|
||||
ptr0 = pair;
|
||||
curMatch = *ptr0;
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
pos++;
|
||||
_cyclicBufferPos++;
|
||||
cur++;
|
||||
{
|
||||
UInt32 num = (UInt32)(distances - _distances);
|
||||
*_distances = num - 1;
|
||||
_distances += num;
|
||||
limit -= num;
|
||||
}
|
||||
}
|
||||
while (limit > 0 && --size != 0);
|
||||
*posRes = pos;
|
||||
return limit;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 numProcessed = 0;
|
||||
UInt32 curPos = 2;
|
||||
UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);
|
||||
distances[1] = p->hashNumAvail;
|
||||
while (curPos < limit)
|
||||
{
|
||||
if (p->hashBufPos == p->hashBufPosLimit)
|
||||
{
|
||||
MatchFinderMt_GetNextBlock_Hash(p);
|
||||
distances[1] = numProcessed + p->hashNumAvail;
|
||||
if (p->hashNumAvail >= p->numHashBytes)
|
||||
continue;
|
||||
for (; p->hashNumAvail != 0; p->hashNumAvail--)
|
||||
distances[curPos++] = 0;
|
||||
break;
|
||||
}
|
||||
{
|
||||
UInt32 size = p->hashBufPosLimit - p->hashBufPos;
|
||||
UInt32 lenLimit = p->matchMaxLen;
|
||||
UInt32 pos = p->pos;
|
||||
UInt32 cyclicBufferPos = p->cyclicBufferPos;
|
||||
if (lenLimit >= p->hashNumAvail)
|
||||
lenLimit = p->hashNumAvail;
|
||||
{
|
||||
UInt32 size2 = p->hashNumAvail - lenLimit + 1;
|
||||
if (size2 < size)
|
||||
size = size2;
|
||||
size2 = p->cyclicBufferSize - cyclicBufferPos;
|
||||
if (size2 < size)
|
||||
size = size2;
|
||||
}
|
||||
#ifndef MFMT_GM_INLINE
|
||||
while (curPos < limit && size-- != 0)
|
||||
{
|
||||
UInt32 *startDistances = distances + curPos;
|
||||
UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++],
|
||||
pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
|
||||
startDistances + 1, p->numHashBytes - 1) - startDistances);
|
||||
*startDistances = num - 1;
|
||||
curPos += num;
|
||||
cyclicBufferPos++;
|
||||
pos++;
|
||||
p->buffer++;
|
||||
}
|
||||
#else
|
||||
{
|
||||
UInt32 posRes;
|
||||
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);
|
||||
p->hashBufPos += posRes - pos;
|
||||
cyclicBufferPos += posRes - pos;
|
||||
p->buffer += posRes - pos;
|
||||
pos = posRes;
|
||||
}
|
||||
#endif
|
||||
|
||||
numProcessed += pos - p->pos;
|
||||
p->hashNumAvail -= pos - p->pos;
|
||||
p->pos = pos;
|
||||
if (cyclicBufferPos == p->cyclicBufferSize)
|
||||
cyclicBufferPos = 0;
|
||||
p->cyclicBufferPos = cyclicBufferPos;
|
||||
}
|
||||
}
|
||||
distances[0] = curPos;
|
||||
}
|
||||
|
||||
void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
|
||||
{
|
||||
CMtSync *sync = &p->hashSync;
|
||||
if (!sync->needStart)
|
||||
{
|
||||
CriticalSection_Enter(&sync->cs);
|
||||
sync->csWasEntered = True;
|
||||
}
|
||||
|
||||
BtGetMatches(p, p->btBuf + (globalBlockIndex & kMtBtNumBlocksMask) * kMtBtBlockSize);
|
||||
|
||||
if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
|
||||
{
|
||||
UInt32 subValue = p->pos - p->cyclicBufferSize;
|
||||
MatchFinder_Normalize3(subValue, p->son, p->cyclicBufferSize * 2);
|
||||
p->pos -= subValue;
|
||||
}
|
||||
|
||||
if (!sync->needStart)
|
||||
{
|
||||
CriticalSection_Leave(&sync->cs);
|
||||
sync->csWasEntered = False;
|
||||
}
|
||||
}
|
||||
|
||||
void BtThreadFunc(CMatchFinderMt *mt)
|
||||
{
|
||||
CMtSync *p = &mt->btSync;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 blockIndex = 0;
|
||||
Event_Wait(&p->canStart);
|
||||
Event_Set(&p->wasStarted);
|
||||
for (;;)
|
||||
{
|
||||
if (p->exit)
|
||||
return;
|
||||
if (p->stopWriting)
|
||||
{
|
||||
p->numProcessedBlocks = blockIndex;
|
||||
MtSync_StopWriting(&mt->hashSync);
|
||||
Event_Set(&p->wasStopped);
|
||||
break;
|
||||
}
|
||||
Semaphore_Wait(&p->freeSemaphore);
|
||||
BtFillBlock(mt, blockIndex++);
|
||||
Semaphore_Release1(&p->filledSemaphore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MatchFinderMt_Construct(CMatchFinderMt *p)
|
||||
{
|
||||
p->hashBuf = 0;
|
||||
MtSync_Construct(&p->hashSync);
|
||||
MtSync_Construct(&p->btSync);
|
||||
}
|
||||
|
||||
void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
|
||||
{
|
||||
alloc->Free(alloc, p->hashBuf);
|
||||
p->hashBuf = 0;
|
||||
}
|
||||
|
||||
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
|
||||
{
|
||||
MtSync_Destruct(&p->hashSync);
|
||||
MtSync_Destruct(&p->btSync);
|
||||
MatchFinderMt_FreeMem(p, alloc);
|
||||
}
|
||||
|
||||
#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks)
|
||||
#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
|
||||
|
||||
static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
|
||||
static unsigned MY_STD_CALL BtThreadFunc2(void *p)
|
||||
{
|
||||
Byte allocaDummy[0x180];
|
||||
int i = 0;
|
||||
for (i = 0; i < 16; i++)
|
||||
allocaDummy[i] = (Byte)i;
|
||||
BtThreadFunc((CMatchFinderMt *)p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc)
|
||||
{
|
||||
CMatchFinder *mf = p->MatchFinder;
|
||||
p->historySize = historySize;
|
||||
if (kMtBtBlockSize <= matchMaxLen * 4)
|
||||
return SZ_ERROR_PARAM;
|
||||
if (p->hashBuf == 0)
|
||||
{
|
||||
p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
|
||||
if (p->hashBuf == 0)
|
||||
return SZ_ERROR_MEM;
|
||||
p->btBuf = p->hashBuf + kHashBufferSize;
|
||||
}
|
||||
keepAddBufferBefore += (kHashBufferSize + kBtBufferSize);
|
||||
keepAddBufferAfter += kMtHashBlockSize;
|
||||
if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc))
|
||||
return SZ_ERROR_MEM;
|
||||
|
||||
RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p, kMtHashNumBlocks));
|
||||
RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p, kMtBtNumBlocks));
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
/* Call it after ReleaseStream / SetStream */
|
||||
void MatchFinderMt_Init(CMatchFinderMt *p)
|
||||
{
|
||||
CMatchFinder *mf = p->MatchFinder;
|
||||
p->btBufPos = p->btBufPosLimit = 0;
|
||||
p->hashBufPos = p->hashBufPosLimit = 0;
|
||||
MatchFinder_Init(mf);
|
||||
p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf);
|
||||
p->btNumAvailBytes = 0;
|
||||
p->lzPos = p->historySize + 1;
|
||||
|
||||
p->hash = mf->hash;
|
||||
p->fixedHashSize = mf->fixedHashSize;
|
||||
p->crc = mf->crc;
|
||||
|
||||
p->son = mf->son;
|
||||
p->matchMaxLen = mf->matchMaxLen;
|
||||
p->numHashBytes = mf->numHashBytes;
|
||||
p->pos = mf->pos;
|
||||
p->buffer = mf->buffer;
|
||||
p->cyclicBufferPos = mf->cyclicBufferPos;
|
||||
p->cyclicBufferSize = mf->cyclicBufferSize;
|
||||
p->cutValue = mf->cutValue;
|
||||
}
|
||||
|
||||
/* ReleaseStream is required to finish multithreading */
|
||||
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)
|
||||
{
|
||||
MtSync_StopWriting(&p->btSync);
|
||||
/* p->MatchFinder->ReleaseStream(); */
|
||||
}
|
||||
|
||||
void MatchFinderMt_Normalize(CMatchFinderMt *p)
|
||||
{
|
||||
MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize);
|
||||
p->lzPos = p->historySize + 1;
|
||||
}
|
||||
|
||||
void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
|
||||
{
|
||||
UInt32 blockIndex;
|
||||
MtSync_GetNextBlock(&p->btSync);
|
||||
blockIndex = ((p->btSync.numProcessedBlocks - 1) & kMtBtNumBlocksMask);
|
||||
p->btBufPosLimit = p->btBufPos = blockIndex * kMtBtBlockSize;
|
||||
p->btBufPosLimit += p->btBuf[p->btBufPos++];
|
||||
p->btNumAvailBytes = p->btBuf[p->btBufPos++];
|
||||
if (p->lzPos >= kMtMaxValForNormalize - kMtBtBlockSize)
|
||||
MatchFinderMt_Normalize(p);
|
||||
}
|
||||
|
||||
const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
|
||||
{
|
||||
return p->pointerToCurPos;
|
||||
}
|
||||
|
||||
#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);
|
||||
|
||||
UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)
|
||||
{
|
||||
GET_NEXT_BLOCK_IF_REQUIRED;
|
||||
return p->btNumAvailBytes;
|
||||
}
|
||||
|
||||
Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index)
|
||||
{
|
||||
return p->pointerToCurPos[index];
|
||||
}
|
||||
|
||||
UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
||||
{
|
||||
UInt32 hash2Value, curMatch2;
|
||||
UInt32 *hash = p->hash;
|
||||
const Byte *cur = p->pointerToCurPos;
|
||||
UInt32 lzPos = p->lzPos;
|
||||
MT_HASH2_CALC
|
||||
|
||||
curMatch2 = hash[hash2Value];
|
||||
hash[hash2Value] = lzPos;
|
||||
|
||||
if (curMatch2 >= matchMinPos)
|
||||
if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||
{
|
||||
*distances++ = 2;
|
||||
*distances++ = lzPos - curMatch2 - 1;
|
||||
}
|
||||
return distances;
|
||||
}
|
||||
|
||||
UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
||||
{
|
||||
UInt32 hash2Value, hash3Value, curMatch2, curMatch3;
|
||||
UInt32 *hash = p->hash;
|
||||
const Byte *cur = p->pointerToCurPos;
|
||||
UInt32 lzPos = p->lzPos;
|
||||
MT_HASH3_CALC
|
||||
|
||||
curMatch2 = hash[ hash2Value];
|
||||
curMatch3 = hash[kFix3HashSize + hash3Value];
|
||||
|
||||
hash[ hash2Value] =
|
||||
hash[kFix3HashSize + hash3Value] =
|
||||
lzPos;
|
||||
|
||||
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||
{
|
||||
distances[1] = lzPos - curMatch2 - 1;
|
||||
if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
|
||||
{
|
||||
distances[0] = 3;
|
||||
return distances + 2;
|
||||
}
|
||||
distances[0] = 2;
|
||||
distances += 2;
|
||||
}
|
||||
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
|
||||
{
|
||||
*distances++ = 3;
|
||||
*distances++ = lzPos - curMatch3 - 1;
|
||||
}
|
||||
return distances;
|
||||
}
|
||||
|
||||
/*
|
||||
UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
||||
{
|
||||
UInt32 hash2Value, hash3Value, hash4Value, curMatch2, curMatch3, curMatch4;
|
||||
UInt32 *hash = p->hash;
|
||||
const Byte *cur = p->pointerToCurPos;
|
||||
UInt32 lzPos = p->lzPos;
|
||||
MT_HASH4_CALC
|
||||
|
||||
curMatch2 = hash[ hash2Value];
|
||||
curMatch3 = hash[kFix3HashSize + hash3Value];
|
||||
curMatch4 = hash[kFix4HashSize + hash4Value];
|
||||
|
||||
hash[ hash2Value] =
|
||||
hash[kFix3HashSize + hash3Value] =
|
||||
hash[kFix4HashSize + hash4Value] =
|
||||
lzPos;
|
||||
|
||||
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||
{
|
||||
distances[1] = lzPos - curMatch2 - 1;
|
||||
if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
|
||||
{
|
||||
distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3;
|
||||
return distances + 2;
|
||||
}
|
||||
distances[0] = 2;
|
||||
distances += 2;
|
||||
}
|
||||
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
|
||||
{
|
||||
distances[1] = lzPos - curMatch3 - 1;
|
||||
if (cur[(ptrdiff_t)curMatch3 - lzPos + 3] == cur[3])
|
||||
{
|
||||
distances[0] = 4;
|
||||
return distances + 2;
|
||||
}
|
||||
distances[0] = 3;
|
||||
distances += 2;
|
||||
}
|
||||
|
||||
if (curMatch4 >= matchMinPos)
|
||||
if (
|
||||
cur[(ptrdiff_t)curMatch4 - lzPos] == cur[0] &&
|
||||
cur[(ptrdiff_t)curMatch4 - lzPos + 3] == cur[3]
|
||||
)
|
||||
{
|
||||
*distances++ = 4;
|
||||
*distances++ = lzPos - curMatch4 - 1;
|
||||
}
|
||||
return distances;
|
||||
}
|
||||
*/
|
||||
|
||||
#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++;
|
||||
|
||||
UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||
{
|
||||
const UInt32 *btBuf = p->btBuf + p->btBufPos;
|
||||
UInt32 len = *btBuf++;
|
||||
p->btBufPos += 1 + len;
|
||||
p->btNumAvailBytes--;
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < len; i += 2)
|
||||
{
|
||||
*distances++ = *btBuf++;
|
||||
*distances++ = *btBuf++;
|
||||
}
|
||||
}
|
||||
INCREASE_LZ_POS
|
||||
return len;
|
||||
}
|
||||
|
||||
UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||
{
|
||||
const UInt32 *btBuf = p->btBuf + p->btBufPos;
|
||||
UInt32 len = *btBuf++;
|
||||
p->btBufPos += 1 + len;
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
if (p->btNumAvailBytes-- >= 4)
|
||||
len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Condition: there are matches in btBuf with length < p->numHashBytes */
|
||||
UInt32 *distances2;
|
||||
p->btNumAvailBytes--;
|
||||
distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);
|
||||
do
|
||||
{
|
||||
*distances2++ = *btBuf++;
|
||||
*distances2++ = *btBuf++;
|
||||
}
|
||||
while ((len -= 2) != 0);
|
||||
len = (UInt32)(distances2 - (distances));
|
||||
}
|
||||
INCREASE_LZ_POS
|
||||
return len;
|
||||
}
|
||||
|
||||
#define SKIP_HEADER2 do { GET_NEXT_BLOCK_IF_REQUIRED
|
||||
#define SKIP_HEADER(n) SKIP_HEADER2 if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
|
||||
#define SKIP_FOOTER } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0);
|
||||
|
||||
void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
|
||||
{
|
||||
SKIP_HEADER2 { p->btNumAvailBytes--;
|
||||
SKIP_FOOTER
|
||||
}
|
||||
|
||||
void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
|
||||
{
|
||||
SKIP_HEADER(2)
|
||||
UInt32 hash2Value;
|
||||
MT_HASH2_CALC
|
||||
hash[hash2Value] = p->lzPos;
|
||||
SKIP_FOOTER
|
||||
}
|
||||
|
||||
void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
|
||||
{
|
||||
SKIP_HEADER(3)
|
||||
UInt32 hash2Value, hash3Value;
|
||||
MT_HASH3_CALC
|
||||
hash[kFix3HashSize + hash3Value] =
|
||||
hash[ hash2Value] =
|
||||
p->lzPos;
|
||||
SKIP_FOOTER
|
||||
}
|
||||
|
||||
/*
|
||||
void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
|
||||
{
|
||||
SKIP_HEADER(4)
|
||||
UInt32 hash2Value, hash3Value, hash4Value;
|
||||
MT_HASH4_CALC
|
||||
hash[kFix4HashSize + hash4Value] =
|
||||
hash[kFix3HashSize + hash3Value] =
|
||||
hash[ hash2Value] =
|
||||
p->lzPos;
|
||||
SKIP_FOOTER
|
||||
}
|
||||
*/
|
||||
|
||||
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
|
||||
{
|
||||
vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
|
||||
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte;
|
||||
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
|
||||
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
|
||||
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
|
||||
switch(p->MatchFinder->numHashBytes)
|
||||
{
|
||||
case 2:
|
||||
p->GetHeadsFunc = GetHeads2;
|
||||
p->MixMatchesFunc = (Mf_Mix_Matches)0;
|
||||
vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip;
|
||||
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches;
|
||||
break;
|
||||
case 3:
|
||||
p->GetHeadsFunc = GetHeads3;
|
||||
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches2;
|
||||
vTable->Skip = (Mf_Skip_Func)MatchFinderMt2_Skip;
|
||||
break;
|
||||
default:
|
||||
/* case 4: */
|
||||
p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;
|
||||
/* p->GetHeadsFunc = GetHeads4; */
|
||||
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
|
||||
vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
|
||||
break;
|
||||
/*
|
||||
default:
|
||||
p->GetHeadsFunc = GetHeads5;
|
||||
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches4;
|
||||
vTable->Skip = (Mf_Skip_Func)MatchFinderMt4_Skip;
|
||||
break;
|
||||
*/
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZFINDMT_H
|
||||
#define __LZFINDMT_H
|
||||
|
||||
#include "Threads.h"
|
||||
#include "LzFind.h"
|
||||
|
||||
#define kMtHashBlockSize (1 << 13)
|
||||
#define kMtHashNumBlocks (1 << 3)
|
||||
#define kMtHashNumBlocksMask (kMtHashNumBlocks - 1)
|
||||
|
||||
#define kMtBtBlockSize (1 << 14)
|
||||
#define kMtBtNumBlocks (1 << 6)
|
||||
#define kMtBtNumBlocksMask (kMtBtNumBlocks - 1)
|
||||
|
||||
typedef struct _CMtSync
|
||||
{
|
||||
Bool wasCreated;
|
||||
Bool needStart;
|
||||
Bool exit;
|
||||
Bool stopWriting;
|
||||
|
||||
CThread thread;
|
||||
CAutoResetEvent canStart;
|
||||
CAutoResetEvent wasStarted;
|
||||
CAutoResetEvent wasStopped;
|
||||
CSemaphore freeSemaphore;
|
||||
CSemaphore filledSemaphore;
|
||||
Bool csWasInitialized;
|
||||
Bool csWasEntered;
|
||||
CCriticalSection cs;
|
||||
UInt32 numProcessedBlocks;
|
||||
} CMtSync;
|
||||
|
||||
typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances);
|
||||
|
||||
/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */
|
||||
#define kMtCacheLineDummy 128
|
||||
|
||||
typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos,
|
||||
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc);
|
||||
|
||||
typedef struct _CMatchFinderMt
|
||||
{
|
||||
/* LZ */
|
||||
const Byte *pointerToCurPos;
|
||||
UInt32 *btBuf;
|
||||
UInt32 btBufPos;
|
||||
UInt32 btBufPosLimit;
|
||||
UInt32 lzPos;
|
||||
UInt32 btNumAvailBytes;
|
||||
|
||||
UInt32 *hash;
|
||||
UInt32 fixedHashSize;
|
||||
UInt32 historySize;
|
||||
const UInt32 *crc;
|
||||
|
||||
Mf_Mix_Matches MixMatchesFunc;
|
||||
|
||||
/* LZ + BT */
|
||||
CMtSync btSync;
|
||||
Byte btDummy[kMtCacheLineDummy];
|
||||
|
||||
/* BT */
|
||||
UInt32 *hashBuf;
|
||||
UInt32 hashBufPos;
|
||||
UInt32 hashBufPosLimit;
|
||||
UInt32 hashNumAvail;
|
||||
|
||||
CLzRef *son;
|
||||
UInt32 matchMaxLen;
|
||||
UInt32 numHashBytes;
|
||||
UInt32 pos;
|
||||
Byte *buffer;
|
||||
UInt32 cyclicBufferPos;
|
||||
UInt32 cyclicBufferSize; /* it must be historySize + 1 */
|
||||
UInt32 cutValue;
|
||||
|
||||
/* BT + Hash */
|
||||
CMtSync hashSync;
|
||||
/* Byte hashDummy[kMtCacheLineDummy]; */
|
||||
|
||||
/* Hash */
|
||||
Mf_GetHeads GetHeadsFunc;
|
||||
CMatchFinder *MatchFinder;
|
||||
} CMatchFinderMt;
|
||||
|
||||
void MatchFinderMt_Construct(CMatchFinderMt *p);
|
||||
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc);
|
||||
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc);
|
||||
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
|
||||
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
|
||||
|
||||
#endif
|
|
@ -1,54 +0,0 @@
|
|||
/* LzHash.h -- HASH functions for LZ algorithms
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZHASH_H
|
||||
#define __LZHASH_H
|
||||
|
||||
#define kHash2Size (1 << 10)
|
||||
#define kHash3Size (1 << 16)
|
||||
#define kHash4Size (1 << 20)
|
||||
|
||||
#define kFix3HashSize (kHash2Size)
|
||||
#define kFix4HashSize (kHash2Size + kHash3Size)
|
||||
#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
|
||||
|
||||
#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
|
||||
|
||||
#define HASH3_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
|
||||
|
||||
#define HASH4_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
||||
hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
|
||||
|
||||
#define HASH5_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
||||
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
|
||||
hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
|
||||
hash4Value &= (kHash4Size - 1); }
|
||||
|
||||
/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
|
||||
#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
|
||||
|
||||
|
||||
#define MT_HASH2_CALC \
|
||||
hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
|
||||
|
||||
#define MT_HASH3_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
|
||||
|
||||
#define MT_HASH4_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
||||
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,223 +0,0 @@
|
|||
/* LzmaDec.h -- LZMA Decoder
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMADEC_H
|
||||
#define __LZMADEC_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
/* #define _LZMA_PROB32 */
|
||||
/* _LZMA_PROB32 can increase the speed on some CPUs,
|
||||
but memory usage for CLzmaDec::probs will be doubled in that case */
|
||||
|
||||
#ifdef _LZMA_PROB32
|
||||
#define CLzmaProb UInt32
|
||||
#else
|
||||
#define CLzmaProb UInt16
|
||||
#endif
|
||||
|
||||
|
||||
/* ---------- LZMA Properties ---------- */
|
||||
|
||||
#define LZMA_PROPS_SIZE 5
|
||||
|
||||
typedef struct _CLzmaProps
|
||||
{
|
||||
unsigned lc, lp, pb;
|
||||
UInt32 dicSize;
|
||||
} CLzmaProps;
|
||||
|
||||
/* LzmaProps_Decode - decodes properties
|
||||
Returns:
|
||||
SZ_OK
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
*/
|
||||
|
||||
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
|
||||
|
||||
|
||||
/* ---------- LZMA Decoder state ---------- */
|
||||
|
||||
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
|
||||
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
|
||||
|
||||
#define LZMA_REQUIRED_INPUT_MAX 20
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CLzmaProps prop;
|
||||
CLzmaProb *probs;
|
||||
Byte *dic;
|
||||
const Byte *buf;
|
||||
UInt32 range, code;
|
||||
SizeT dicPos;
|
||||
SizeT dicBufSize;
|
||||
UInt32 processedPos;
|
||||
UInt32 checkDicSize;
|
||||
unsigned state;
|
||||
UInt32 reps[4];
|
||||
unsigned remainLen;
|
||||
int needFlush;
|
||||
int needInitState;
|
||||
UInt32 numProbs;
|
||||
unsigned tempBufSize;
|
||||
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
|
||||
} CLzmaDec;
|
||||
|
||||
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
|
||||
|
||||
void LzmaDec_Init(CLzmaDec *p);
|
||||
|
||||
/* There are two types of LZMA streams:
|
||||
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
||||
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA_FINISH_ANY, /* finish at any point */
|
||||
LZMA_FINISH_END /* block must be finished at the end */
|
||||
} ELzmaFinishMode;
|
||||
|
||||
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
|
||||
|
||||
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.
|
||||
|
||||
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
|
||||
and output value of destLen will be less than output buffer size limit.
|
||||
You can check status result also.
|
||||
|
||||
You can use multiple checks to test data integrity after full decompression:
|
||||
1) Check Result and "status" variable.
|
||||
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
|
||||
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
|
||||
You must use correct finish mode in that case. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
||||
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
||||
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
|
||||
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 */
|
||||
} ELzmaStatus;
|
||||
|
||||
/* ELzmaStatus is used only as output value for function call */
|
||||
|
||||
|
||||
/* ---------- Interfaces ---------- */
|
||||
|
||||
/* There are 3 levels of interfaces:
|
||||
1) Dictionary Interface
|
||||
2) Buffer Interface
|
||||
3) One Call Interface
|
||||
You can select any of these interfaces, but don't mix functions from different
|
||||
groups for same object. */
|
||||
|
||||
|
||||
/* There are two variants to allocate state for Dictionary Interface:
|
||||
1) LzmaDec_Allocate / LzmaDec_Free
|
||||
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
|
||||
You can use variant 2, if you set dictionary buffer manually.
|
||||
For Buffer Interface you must always use variant 1.
|
||||
|
||||
LzmaDec_Allocate* can return:
|
||||
SZ_OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
*/
|
||||
|
||||
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
|
||||
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
|
||||
|
||||
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
|
||||
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
||||
|
||||
/* ---------- Dictionary Interface ---------- */
|
||||
|
||||
/* You can use it, if you want to eliminate the overhead for data copying from
|
||||
dictionary to some other external buffer.
|
||||
You must work with CLzmaDec variables directly in this interface.
|
||||
|
||||
STEPS:
|
||||
LzmaDec_Constr()
|
||||
LzmaDec_Allocate()
|
||||
for (each new stream)
|
||||
{
|
||||
LzmaDec_Init()
|
||||
while (it needs more decompression)
|
||||
{
|
||||
LzmaDec_DecodeToDic()
|
||||
use data from CLzmaDec::dic and update CLzmaDec::dicPos
|
||||
}
|
||||
}
|
||||
LzmaDec_Free()
|
||||
*/
|
||||
|
||||
/* LzmaDec_DecodeToDic
|
||||
|
||||
The decoding to internal dictionary buffer (CLzmaDec::dic).
|
||||
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (dicLimit).
|
||||
LZMA_FINISH_ANY - Decode just dicLimit bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after dicLimit.
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
LZMA_STATUS_NEEDS_MORE_INPUT
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||
SZ_ERROR_DATA - Data error
|
||||
*/
|
||||
|
||||
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
|
||||
/* ---------- Buffer Interface ---------- */
|
||||
|
||||
/* It's zlib-like interface.
|
||||
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
|
||||
to work with CLzmaDec variables manually.
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
*/
|
||||
|
||||
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
|
||||
/* ---------- One Call Interface ---------- */
|
||||
|
||||
/* LzmaDecode
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||
SZ_ERROR_DATA - Data error
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||
*/
|
||||
|
||||
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||
ELzmaStatus *status, ISzAlloc *alloc);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,72 +0,0 @@
|
|||
/* LzmaEnc.h -- LZMA Encoder
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMAENC_H
|
||||
#define __LZMAENC_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#define LZMA_PROPS_SIZE 5
|
||||
|
||||
typedef struct _CLzmaEncProps
|
||||
{
|
||||
int level; /* 0 <= level <= 9 */
|
||||
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
|
||||
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
|
||||
default = (1 << 24) */
|
||||
int lc; /* 0 <= lc <= 8, default = 3 */
|
||||
int lp; /* 0 <= lp <= 4, default = 0 */
|
||||
int pb; /* 0 <= pb <= 4, default = 2 */
|
||||
int algo; /* 0 - fast, 1 - normal, default = 1 */
|
||||
int fb; /* 5 <= fb <= 273, default = 32 */
|
||||
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
|
||||
int numHashBytes; /* 2, 3 or 4, default = 4 */
|
||||
UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
|
||||
unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
|
||||
int numThreads; /* 1 or 2, default = 2 */
|
||||
} CLzmaEncProps;
|
||||
|
||||
void LzmaEncProps_Init(CLzmaEncProps *p);
|
||||
void LzmaEncProps_Normalize(CLzmaEncProps *p);
|
||||
UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
|
||||
|
||||
|
||||
/* ---------- CLzmaEncHandle Interface ---------- */
|
||||
|
||||
/* LzmaEnc_* functions can return the following exit codes:
|
||||
Returns:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_PARAM - Incorrect paramater in props
|
||||
SZ_ERROR_WRITE - Write callback error.
|
||||
SZ_ERROR_PROGRESS - some break from progress callback
|
||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||
*/
|
||||
|
||||
typedef void * CLzmaEncHandle;
|
||||
|
||||
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
|
||||
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
|
||||
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
|
||||
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
|
||||
/* ---------- One Call Interface ---------- */
|
||||
|
||||
/* LzmaEncode
|
||||
Return code:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_PARAM - Incorrect paramater
|
||||
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||
*/
|
||||
|
||||
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
|
||||
#endif
|
|
@ -1,22 +0,0 @@
|
|||
/* RotateDefs.h -- Rotate functions
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#ifndef __ROTATEDEFS_H
|
||||
#define __ROTATEDEFS_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#include <stdlib.h>
|
||||
#define rotlFixed(x, n) _rotl((x), (n))
|
||||
#define rotrFixed(x, n) _rotr((x), (n))
|
||||
|
||||
#else
|
||||
|
||||
#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||
#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,204 +0,0 @@
|
|||
/* Crypto/Sha256.c -- SHA-256 Hash function
|
||||
2008-11-06 : Igor Pavlov : Public domain
|
||||
This code is based on public domain code from Wei Dai's Crypto++ library. */
|
||||
|
||||
#include "Sha256.h"
|
||||
#include "RotateDefs.h"
|
||||
|
||||
/* define it for speed optimization */
|
||||
/* #define _SHA256_UNROLL */
|
||||
/* #define _SHA256_UNROLL2 */
|
||||
|
||||
void Sha256_Init(CSha256 *p)
|
||||
{
|
||||
p->state[0] = 0x6a09e667;
|
||||
p->state[1] = 0xbb67ae85;
|
||||
p->state[2] = 0x3c6ef372;
|
||||
p->state[3] = 0xa54ff53a;
|
||||
p->state[4] = 0x510e527f;
|
||||
p->state[5] = 0x9b05688c;
|
||||
p->state[6] = 0x1f83d9ab;
|
||||
p->state[7] = 0x5be0cd19;
|
||||
p->count = 0;
|
||||
}
|
||||
|
||||
#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22))
|
||||
#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25))
|
||||
#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3))
|
||||
#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10))
|
||||
|
||||
#define blk0(i) (W[i] = data[i])
|
||||
#define blk2(i) (W[i&15] += s1(W[(i-2)&15]) + W[(i-7)&15] + s0(W[(i-15)&15]))
|
||||
|
||||
#define Ch(x,y,z) (z^(x&(y^z)))
|
||||
#define Maj(x,y,z) ((x&y)|(z&(x|y)))
|
||||
|
||||
#define a(i) T[(0-(i))&7]
|
||||
#define b(i) T[(1-(i))&7]
|
||||
#define c(i) T[(2-(i))&7]
|
||||
#define d(i) T[(3-(i))&7]
|
||||
#define e(i) T[(4-(i))&7]
|
||||
#define f(i) T[(5-(i))&7]
|
||||
#define g(i) T[(6-(i))&7]
|
||||
#define h(i) T[(7-(i))&7]
|
||||
|
||||
|
||||
#ifdef _SHA256_UNROLL2
|
||||
|
||||
#define R(a,b,c,d,e,f,g,h, i) h += S1(e) + Ch(e,f,g) + K[i+j] + (j?blk2(i):blk0(i));\
|
||||
d += h; h += S0(a) + Maj(a, b, c)
|
||||
|
||||
#define RX_8(i) \
|
||||
R(a,b,c,d,e,f,g,h, i); \
|
||||
R(h,a,b,c,d,e,f,g, i+1); \
|
||||
R(g,h,a,b,c,d,e,f, i+2); \
|
||||
R(f,g,h,a,b,c,d,e, i+3); \
|
||||
R(e,f,g,h,a,b,c,d, i+4); \
|
||||
R(d,e,f,g,h,a,b,c, i+5); \
|
||||
R(c,d,e,f,g,h,a,b, i+6); \
|
||||
R(b,c,d,e,f,g,h,a, i+7)
|
||||
|
||||
#else
|
||||
|
||||
#define R(i) h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j?blk2(i):blk0(i));\
|
||||
d(i) += h(i); h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
|
||||
|
||||
#ifdef _SHA256_UNROLL
|
||||
|
||||
#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
const UInt32 K[64] = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
};
|
||||
|
||||
static void Sha256_Transform(UInt32 *state, const UInt32 *data)
|
||||
{
|
||||
UInt32 W[16];
|
||||
unsigned j;
|
||||
#ifdef _SHA256_UNROLL2
|
||||
UInt32 a,b,c,d,e,f,g,h;
|
||||
a = state[0];
|
||||
b = state[1];
|
||||
c = state[2];
|
||||
d = state[3];
|
||||
e = state[4];
|
||||
f = state[5];
|
||||
g = state[6];
|
||||
h = state[7];
|
||||
#else
|
||||
UInt32 T[8];
|
||||
for (j = 0; j < 8; j++)
|
||||
T[j] = state[j];
|
||||
#endif
|
||||
|
||||
for (j = 0; j < 64; j += 16)
|
||||
{
|
||||
#if defined(_SHA256_UNROLL) || defined(_SHA256_UNROLL2)
|
||||
RX_8(0); RX_8(8);
|
||||
#else
|
||||
unsigned i;
|
||||
for (i = 0; i < 16; i++) { R(i); }
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _SHA256_UNROLL2
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
state[5] += f;
|
||||
state[6] += g;
|
||||
state[7] += h;
|
||||
#else
|
||||
for (j = 0; j < 8; j++)
|
||||
state[j] += T[j];
|
||||
#endif
|
||||
|
||||
/* Wipe variables */
|
||||
/* memset(W, 0, sizeof(W)); */
|
||||
/* memset(T, 0, sizeof(T)); */
|
||||
}
|
||||
|
||||
#undef S0
|
||||
#undef S1
|
||||
#undef s0
|
||||
#undef s1
|
||||
|
||||
static void Sha256_WriteByteBlock(CSha256 *p)
|
||||
{
|
||||
UInt32 data32[16];
|
||||
unsigned i;
|
||||
for (i = 0; i < 16; i++)
|
||||
data32[i] =
|
||||
((UInt32)(p->buffer[i * 4 ]) << 24) +
|
||||
((UInt32)(p->buffer[i * 4 + 1]) << 16) +
|
||||
((UInt32)(p->buffer[i * 4 + 2]) << 8) +
|
||||
((UInt32)(p->buffer[i * 4 + 3]));
|
||||
Sha256_Transform(p->state, data32);
|
||||
}
|
||||
|
||||
void Sha256_Update(CSha256 *p, const Byte *data, size_t size)
|
||||
{
|
||||
UInt32 curBufferPos = (UInt32)p->count & 0x3F;
|
||||
while (size > 0)
|
||||
{
|
||||
p->buffer[curBufferPos++] = *data++;
|
||||
p->count++;
|
||||
size--;
|
||||
if (curBufferPos == 64)
|
||||
{
|
||||
curBufferPos = 0;
|
||||
Sha256_WriteByteBlock(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Sha256_Final(CSha256 *p, Byte *digest)
|
||||
{
|
||||
UInt64 lenInBits = (p->count << 3);
|
||||
UInt32 curBufferPos = (UInt32)p->count & 0x3F;
|
||||
unsigned i;
|
||||
p->buffer[curBufferPos++] = 0x80;
|
||||
while (curBufferPos != (64 - 8))
|
||||
{
|
||||
curBufferPos &= 0x3F;
|
||||
if (curBufferPos == 0)
|
||||
Sha256_WriteByteBlock(p);
|
||||
p->buffer[curBufferPos++] = 0;
|
||||
}
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
p->buffer[curBufferPos++] = (Byte)(lenInBits >> 56);
|
||||
lenInBits <<= 8;
|
||||
}
|
||||
Sha256_WriteByteBlock(p);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
*digest++ = (Byte)((p->state[i] >> 24) & 0xFF);
|
||||
*digest++ = (Byte)((p->state[i] >> 16) & 0xFF);
|
||||
*digest++ = (Byte)((p->state[i] >> 8) & 0xFF);
|
||||
*digest++ = (Byte)((p->state[i]) & 0xFF);
|
||||
}
|
||||
Sha256_Init(p);
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/* Crypto/Sha256.h -- SHA-256 Hash function
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __CRYPTO_SHA256_H
|
||||
#define __CRYPTO_SHA256_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#define SHA256_DIGEST_SIZE 32
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 state[8];
|
||||
UInt64 count;
|
||||
Byte buffer[64];
|
||||
} CSha256;
|
||||
|
||||
void Sha256_Init(CSha256 *p);
|
||||
void Sha256_Update(CSha256 *p, const Byte *data, size_t size);
|
||||
void Sha256_Final(CSha256 *p, Byte *digest);
|
||||
|
||||
#endif
|
|
@ -1,95 +0,0 @@
|
|||
/* Sort.c -- Sort functions
|
||||
2008-08-17
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#include "Sort.h"
|
||||
|
||||
#define HeapSortDown(p, k, size, temp) \
|
||||
{ for (;;) { \
|
||||
UInt32 s = (k << 1); \
|
||||
if (s > size) break; \
|
||||
if (s < size && p[s + 1] > p[s]) s++; \
|
||||
if (temp >= p[s]) break; \
|
||||
p[k] = p[s]; k = s; \
|
||||
} p[k] = temp; }
|
||||
|
||||
void HeapSort(UInt32 *p, UInt32 size)
|
||||
{
|
||||
if (size <= 1)
|
||||
return;
|
||||
p--;
|
||||
{
|
||||
UInt32 i = size / 2;
|
||||
do
|
||||
{
|
||||
UInt32 temp = p[i];
|
||||
UInt32 k = i;
|
||||
HeapSortDown(p, k, size, temp)
|
||||
}
|
||||
while (--i != 0);
|
||||
}
|
||||
/*
|
||||
do
|
||||
{
|
||||
UInt32 k = 1;
|
||||
UInt32 temp = p[size];
|
||||
p[size--] = p[1];
|
||||
HeapSortDown(p, k, size, temp)
|
||||
}
|
||||
while (size > 1);
|
||||
*/
|
||||
while (size > 3)
|
||||
{
|
||||
UInt32 temp = p[size];
|
||||
UInt32 k = (p[3] > p[2]) ? 3 : 2;
|
||||
p[size--] = p[1];
|
||||
p[1] = p[k];
|
||||
HeapSortDown(p, k, size, temp)
|
||||
}
|
||||
{
|
||||
UInt32 temp = p[size];
|
||||
p[size] = p[1];
|
||||
if (size > 2 && p[2] < temp)
|
||||
{
|
||||
p[1] = p[2];
|
||||
p[2] = temp;
|
||||
}
|
||||
else
|
||||
p[1] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#define HeapSortRefDown(p, vals, n, size, temp) \
|
||||
{ UInt32 k = n; UInt32 val = vals[temp]; for (;;) { \
|
||||
UInt32 s = (k << 1); \
|
||||
if (s > size) break; \
|
||||
if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \
|
||||
if (val >= vals[p[s]]) break; \
|
||||
p[k] = p[s]; k = s; \
|
||||
} p[k] = temp; }
|
||||
|
||||
void HeapSortRef(UInt32 *p, UInt32 *vals, UInt32 size)
|
||||
{
|
||||
if (size <= 1)
|
||||
return;
|
||||
p--;
|
||||
{
|
||||
UInt32 i = size / 2;
|
||||
do
|
||||
{
|
||||
UInt32 temp = p[i];
|
||||
HeapSortRefDown(p, vals, i, size, temp);
|
||||
}
|
||||
while (--i != 0);
|
||||
}
|
||||
do
|
||||
{
|
||||
UInt32 temp = p[size];
|
||||
p[size--] = p[1];
|
||||
HeapSortRefDown(p, vals, 1, size, temp);
|
||||
}
|
||||
while (size > 1);
|
||||
}
|
||||
*/
|
|
@ -1,14 +0,0 @@
|
|||
/* Sort.h -- Sort functions
|
||||
2008-03-19
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#ifndef __7Z_SORT_H
|
||||
#define __7Z_SORT_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
void HeapSort(UInt32 *p, UInt32 size);
|
||||
/* void HeapSortRef(UInt32 *p, UInt32 *vals, UInt32 size); */
|
||||
|
||||
#endif
|
|
@ -1,109 +0,0 @@
|
|||
/* Threads.c -- multithreading library
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#include "Threads.h"
|
||||
#include <process.h>
|
||||
|
||||
static WRes GetError()
|
||||
{
|
||||
DWORD res = GetLastError();
|
||||
return (res) ? (WRes)(res) : 1;
|
||||
}
|
||||
|
||||
WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); }
|
||||
WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
|
||||
|
||||
static WRes MyCloseHandle(HANDLE *h)
|
||||
{
|
||||
if (*h != NULL)
|
||||
if (!CloseHandle(*h))
|
||||
return GetError();
|
||||
*h = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 */
|
||||
thread->handle =
|
||||
/* CreateThread(0, 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. */
|
||||
return HandleToWRes(thread->handle);
|
||||
}
|
||||
|
||||
WRes WaitObject(HANDLE h)
|
||||
{
|
||||
return (WRes)WaitForSingleObject(h, INFINITE);
|
||||
}
|
||||
|
||||
WRes Thread_Wait(CThread *thread)
|
||||
{
|
||||
if (thread->handle == NULL)
|
||||
return 1;
|
||||
return WaitObject(thread->handle);
|
||||
}
|
||||
|
||||
WRes Thread_Close(CThread *thread)
|
||||
{
|
||||
return MyCloseHandle(&thread->handle);
|
||||
}
|
||||
|
||||
WRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled)
|
||||
{
|
||||
p->handle = CreateEvent(NULL, manualReset, (initialSignaled ? TRUE : FALSE), NULL);
|
||||
return HandleToWRes(p->handle);
|
||||
}
|
||||
|
||||
WRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled)
|
||||
{ return Event_Create(p, TRUE, initialSignaled); }
|
||||
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p)
|
||||
{ return ManualResetEvent_Create(p, 0); }
|
||||
|
||||
WRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled)
|
||||
{ return Event_Create(p, FALSE, initialSignaled); }
|
||||
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p)
|
||||
{ return AutoResetEvent_Create(p, 0); }
|
||||
|
||||
WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(p->handle)); }
|
||||
WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(p->handle)); }
|
||||
WRes Event_Wait(CEvent *p) { return WaitObject(p->handle); }
|
||||
WRes Event_Close(CEvent *p) { return MyCloseHandle(&p->handle); }
|
||||
|
||||
|
||||
WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount)
|
||||
{
|
||||
p->handle = CreateSemaphore(NULL, (LONG)initiallyCount, (LONG)maxCount, NULL);
|
||||
return HandleToWRes(p->handle);
|
||||
}
|
||||
|
||||
WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
|
||||
{
|
||||
return BOOLToWRes(ReleaseSemaphore(p->handle, releaseCount, previousCount));
|
||||
}
|
||||
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount)
|
||||
{
|
||||
return Semaphore_Release(p, (LONG)releaseCount, NULL);
|
||||
}
|
||||
WRes Semaphore_Release1(CSemaphore *p)
|
||||
{
|
||||
return Semaphore_ReleaseN(p, 1);
|
||||
}
|
||||
|
||||
WRes Semaphore_Wait(CSemaphore *p) { return WaitObject(p->handle); }
|
||||
WRes Semaphore_Close(CSemaphore *p) { return MyCloseHandle(&p->handle); }
|
||||
|
||||
WRes CriticalSection_Init(CCriticalSection *p)
|
||||
{
|
||||
/* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
|
||||
__try
|
||||
{
|
||||
InitializeCriticalSection(p);
|
||||
/* InitializeCriticalSectionAndSpinCount(p, 0); */
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) { return 1; }
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
/* Threads.h -- multithreading library
|
||||
2008-11-22 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_THRESDS_H
|
||||
#define __7Z_THRESDS_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
typedef struct _CThread
|
||||
{
|
||||
HANDLE handle;
|
||||
} CThread;
|
||||
|
||||
#define Thread_Construct(thread) (thread)->handle = NULL
|
||||
#define Thread_WasCreated(thread) ((thread)->handle != NULL)
|
||||
|
||||
typedef unsigned THREAD_FUNC_RET_TYPE;
|
||||
#define THREAD_FUNC_CALL_TYPE MY_STD_CALL
|
||||
#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
|
||||
|
||||
WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter);
|
||||
WRes Thread_Wait(CThread *thread);
|
||||
WRes Thread_Close(CThread *thread);
|
||||
|
||||
typedef struct _CEvent
|
||||
{
|
||||
HANDLE handle;
|
||||
} CEvent;
|
||||
|
||||
typedef CEvent CAutoResetEvent;
|
||||
typedef CEvent CManualResetEvent;
|
||||
|
||||
#define Event_Construct(event) (event)->handle = NULL
|
||||
#define Event_IsCreated(event) ((event)->handle != NULL)
|
||||
|
||||
WRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled);
|
||||
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event);
|
||||
WRes AutoResetEvent_Create(CAutoResetEvent *event, int initialSignaled);
|
||||
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *event);
|
||||
WRes Event_Set(CEvent *event);
|
||||
WRes Event_Reset(CEvent *event);
|
||||
WRes Event_Wait(CEvent *event);
|
||||
WRes Event_Close(CEvent *event);
|
||||
|
||||
|
||||
typedef struct _CSemaphore
|
||||
{
|
||||
HANDLE handle;
|
||||
} CSemaphore;
|
||||
|
||||
#define Semaphore_Construct(p) (p)->handle = NULL
|
||||
|
||||
WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount);
|
||||
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
|
||||
WRes Semaphore_Release1(CSemaphore *p);
|
||||
WRes Semaphore_Wait(CSemaphore *p);
|
||||
WRes Semaphore_Close(CSemaphore *p);
|
||||
|
||||
|
||||
typedef CRITICAL_SECTION CCriticalSection;
|
||||
|
||||
WRes CriticalSection_Init(CCriticalSection *p);
|
||||
#define CriticalSection_Delete(p) DeleteCriticalSection(p)
|
||||
#define CriticalSection_Enter(p) EnterCriticalSection(p)
|
||||
#define CriticalSection_Leave(p) LeaveCriticalSection(p)
|
||||
|
||||
#endif
|
||||
|
|
@ -1,208 +0,0 @@
|
|||
/* Types.h -- Basic types
|
||||
2008-11-23 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_TYPES_H
|
||||
#define __7Z_TYPES_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#define SZ_OK 0
|
||||
|
||||
#define SZ_ERROR_DATA 1
|
||||
#define SZ_ERROR_MEM 2
|
||||
#define SZ_ERROR_CRC 3
|
||||
#define SZ_ERROR_UNSUPPORTED 4
|
||||
#define SZ_ERROR_PARAM 5
|
||||
#define SZ_ERROR_INPUT_EOF 6
|
||||
#define SZ_ERROR_OUTPUT_EOF 7
|
||||
#define SZ_ERROR_READ 8
|
||||
#define SZ_ERROR_WRITE 9
|
||||
#define SZ_ERROR_PROGRESS 10
|
||||
#define SZ_ERROR_FAIL 11
|
||||
#define SZ_ERROR_THREAD 12
|
||||
|
||||
#define SZ_ERROR_ARCHIVE 16
|
||||
#define SZ_ERROR_NO_ARCHIVE 17
|
||||
|
||||
typedef int SRes;
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef DWORD WRes;
|
||||
#else
|
||||
typedef int WRes;
|
||||
#endif
|
||||
|
||||
#ifndef RINOK
|
||||
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
||||
#endif
|
||||
|
||||
typedef unsigned char Byte;
|
||||
typedef short Int16;
|
||||
typedef unsigned short UInt16;
|
||||
|
||||
#ifdef _LZMA_UINT32_IS_ULONG
|
||||
typedef long Int32;
|
||||
typedef unsigned long UInt32;
|
||||
#else
|
||||
typedef int Int32;
|
||||
typedef unsigned int UInt32;
|
||||
#endif
|
||||
|
||||
#ifdef _SZ_NO_INT_64
|
||||
|
||||
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
|
||||
NOTES: Some code will work incorrectly in that case! */
|
||||
|
||||
typedef long Int64;
|
||||
typedef unsigned long UInt64;
|
||||
|
||||
#else
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
typedef __int64 Int64;
|
||||
typedef unsigned __int64 UInt64;
|
||||
#else
|
||||
typedef long long int Int64;
|
||||
typedef unsigned long long int UInt64;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _LZMA_NO_SYSTEM_SIZE_T
|
||||
typedef UInt32 SizeT;
|
||||
#else
|
||||
typedef size_t SizeT;
|
||||
#endif
|
||||
|
||||
typedef int Bool;
|
||||
#define True 1
|
||||
#define False 0
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#if _MSC_VER >= 1300
|
||||
#define MY_NO_INLINE __declspec(noinline)
|
||||
#else
|
||||
#define MY_NO_INLINE
|
||||
#endif
|
||||
|
||||
#define MY_CDECL __cdecl
|
||||
#define MY_STD_CALL __stdcall
|
||||
#define MY_FAST_CALL MY_NO_INLINE __fastcall
|
||||
|
||||
#else
|
||||
|
||||
#define MY_CDECL
|
||||
#define MY_STD_CALL
|
||||
#define MY_FAST_CALL
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* The following interfaces use first parameter as pointer to structure */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
} ISeqInStream;
|
||||
|
||||
/* it can return SZ_ERROR_INPUT_EOF */
|
||||
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
|
||||
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
|
||||
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t (*Write)(void *p, const void *buf, size_t size);
|
||||
/* Returns: result - the number of actually written bytes.
|
||||
(result < size) means error */
|
||||
} ISeqOutStream;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SZ_SEEK_SET = 0,
|
||||
SZ_SEEK_CUR = 1,
|
||||
SZ_SEEK_END = 2
|
||||
} ESzSeek;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||
} ISeekInStream;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Look)(void *p, void **buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) > input(*size)) is not allowed
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
SRes (*Skip)(void *p, size_t offset);
|
||||
/* offset must be <= output(*size) of Look */
|
||||
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
/* reads directly (without buffer). It's same as ISeqInStream::Read */
|
||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||
} ILookInStream;
|
||||
|
||||
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
|
||||
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
|
||||
|
||||
/* reads via ILookInStream::Read */
|
||||
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
|
||||
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
|
||||
|
||||
#define LookToRead_BUF_SIZE (1 << 14)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ILookInStream s;
|
||||
ISeekInStream *realStream;
|
||||
size_t pos;
|
||||
size_t size;
|
||||
Byte buf[LookToRead_BUF_SIZE];
|
||||
} CLookToRead;
|
||||
|
||||
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
|
||||
void LookToRead_Init(CLookToRead *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream s;
|
||||
ILookInStream *realStream;
|
||||
} CSecToLook;
|
||||
|
||||
void SecToLook_CreateVTable(CSecToLook *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream s;
|
||||
ILookInStream *realStream;
|
||||
} CSecToRead;
|
||||
|
||||
void SecToRead_CreateVTable(CSecToRead *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
|
||||
/* Returns: result. (result != SZ_OK) means break.
|
||||
Value (UInt64)(Int64)-1 for size means unknown value. */
|
||||
} ICompressProgress;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *(*Alloc)(void *p, size_t size);
|
||||
void (*Free)(void *p, void *address); /* address can be 0 */
|
||||
} ISzAlloc;
|
||||
|
||||
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
||||
#define IAlloc_Free(p, a) (p)->Free((p), a)
|
||||
|
||||
#endif
|
|
@ -1,3 +0,0 @@
|
|||
// CompressionMethod.cpp
|
||||
|
||||
#include "StdAfx.h"
|
|
@ -1,50 +0,0 @@
|
|||
// 7zCompressionMode.h
|
||||
|
||||
#ifndef __7Z_COMPRESSION_MODE_H
|
||||
#define __7Z_COMPRESSION_MODE_H
|
||||
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
|
||||
#include "../../Common/MethodProps.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
struct CMethodFull: public CMethod
|
||||
{
|
||||
UInt32 NumInStreams;
|
||||
UInt32 NumOutStreams;
|
||||
bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
|
||||
};
|
||||
|
||||
struct CBind
|
||||
{
|
||||
UInt32 InCoder;
|
||||
UInt32 InStream;
|
||||
UInt32 OutCoder;
|
||||
UInt32 OutStream;
|
||||
};
|
||||
|
||||
struct CCompressionMethodMode
|
||||
{
|
||||
CObjectVector<CMethodFull> Methods;
|
||||
CRecordVector<CBind> Binds;
|
||||
#ifdef COMPRESS_MT
|
||||
UInt32 NumThreads;
|
||||
#endif
|
||||
bool PasswordIsDefined;
|
||||
UString Password;
|
||||
|
||||
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
|
||||
CCompressionMethodMode(): PasswordIsDefined(false)
|
||||
#ifdef COMPRESS_MT
|
||||
, NumThreads(1)
|
||||
#endif
|
||||
{}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
|
@ -1,332 +0,0 @@
|
|||
// 7zDecode.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
#include "../../Common/LockedStream.h"
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
|
||||
#include "7zDecode.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
static void ConvertFolderItemInfoToBindInfo(const CFolder &folder,
|
||||
CBindInfoEx &bindInfo)
|
||||
{
|
||||
bindInfo.Clear();
|
||||
int i;
|
||||
for (i = 0; i < folder.BindPairs.Size(); i++)
|
||||
{
|
||||
NCoderMixer::CBindPair bindPair;
|
||||
bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex;
|
||||
bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex;
|
||||
bindInfo.BindPairs.Add(bindPair);
|
||||
}
|
||||
UInt32 outStreamIndex = 0;
|
||||
for (i = 0; i < folder.Coders.Size(); i++)
|
||||
{
|
||||
NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
|
||||
const CCoderInfo &coderInfo = folder.Coders[i];
|
||||
coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams;
|
||||
coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams;
|
||||
bindInfo.Coders.Add(coderStreamsInfo);
|
||||
bindInfo.CoderMethodIDs.Add(coderInfo.MethodID);
|
||||
for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++)
|
||||
if (folder.FindBindPairForOutStream(outStreamIndex) < 0)
|
||||
bindInfo.OutStreams.Add(outStreamIndex);
|
||||
}
|
||||
for (i = 0; i < folder.PackStreams.Size(); i++)
|
||||
bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]);
|
||||
}
|
||||
|
||||
static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1,
|
||||
const NCoderMixer::CCoderStreamsInfo &a2)
|
||||
{
|
||||
return (a1.NumInStreams == a2.NumInStreams) &&
|
||||
(a1.NumOutStreams == a2.NumOutStreams);
|
||||
}
|
||||
|
||||
static bool AreBindPairsEqual(const NCoderMixer::CBindPair &a1, const NCoderMixer::CBindPair &a2)
|
||||
{
|
||||
return (a1.InIndex == a2.InIndex) &&
|
||||
(a1.OutIndex == a2.OutIndex);
|
||||
}
|
||||
|
||||
static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
|
||||
{
|
||||
if (a1.Coders.Size() != a2.Coders.Size())
|
||||
return false;
|
||||
int i;
|
||||
for (i = 0; i < a1.Coders.Size(); i++)
|
||||
if (!AreCodersEqual(a1.Coders[i], a2.Coders[i]))
|
||||
return false;
|
||||
if (a1.BindPairs.Size() != a2.BindPairs.Size())
|
||||
return false;
|
||||
for (i = 0; i < a1.BindPairs.Size(); i++)
|
||||
if (!AreBindPairsEqual(a1.BindPairs[i], a2.BindPairs[i]))
|
||||
return false;
|
||||
for (i = 0; i < a1.CoderMethodIDs.Size(); i++)
|
||||
if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i])
|
||||
return false;
|
||||
if (a1.InStreams.Size() != a2.InStreams.Size())
|
||||
return false;
|
||||
if (a1.OutStreams.Size() != a2.OutStreams.Size())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
CDecoder::CDecoder(bool multiThread)
|
||||
{
|
||||
#ifndef _ST_MODE
|
||||
multiThread = true;
|
||||
#endif
|
||||
_multiThread = multiThread;
|
||||
_bindInfoExPrevIsDefined = false;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::Decode(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
IInStream *inStream,
|
||||
UInt64 startPos,
|
||||
const UInt64 *packSizes,
|
||||
const CFolder &folderInfo,
|
||||
ISequentialOutStream *outStream,
|
||||
ICompressProgressInfo *compressProgress
|
||||
#ifndef _NO_CRYPTO
|
||||
, ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||
#endif
|
||||
#ifdef COMPRESS_MT
|
||||
, bool mtMode, UInt32 numThreads
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (!folderInfo.CheckStructure())
|
||||
return E_NOTIMPL;
|
||||
#ifndef _NO_CRYPTO
|
||||
passwordIsDefined = false;
|
||||
#endif
|
||||
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
|
||||
|
||||
CLockedInStream lockedInStream;
|
||||
lockedInStream.Init(inStream);
|
||||
|
||||
for (int j = 0; j < folderInfo.PackStreams.Size(); j++)
|
||||
{
|
||||
CLockedSequentialInStreamImp *lockedStreamImpSpec = new
|
||||
CLockedSequentialInStreamImp;
|
||||
CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
|
||||
lockedStreamImpSpec->Init(&lockedInStream, startPos);
|
||||
startPos += packSizes[j];
|
||||
|
||||
CLimitedSequentialInStream *streamSpec = new
|
||||
CLimitedSequentialInStream;
|
||||
CMyComPtr<ISequentialInStream> inStream = streamSpec;
|
||||
streamSpec->SetStream(lockedStreamImp);
|
||||
streamSpec->Init(packSizes[j]);
|
||||
inStreams.Add(inStream);
|
||||
}
|
||||
|
||||
int numCoders = folderInfo.Coders.Size();
|
||||
|
||||
CBindInfoEx bindInfo;
|
||||
ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo);
|
||||
bool createNewCoders;
|
||||
if (!_bindInfoExPrevIsDefined)
|
||||
createNewCoders = true;
|
||||
else
|
||||
createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);
|
||||
if (createNewCoders)
|
||||
{
|
||||
int i;
|
||||
_decoders.Clear();
|
||||
// _decoders2.Clear();
|
||||
|
||||
_mixerCoder.Release();
|
||||
|
||||
if (_multiThread)
|
||||
{
|
||||
_mixerCoderMTSpec = new NCoderMixer::CCoderMixer2MT;
|
||||
_mixerCoder = _mixerCoderMTSpec;
|
||||
_mixerCoderCommon = _mixerCoderMTSpec;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _ST_MODE
|
||||
_mixerCoderSTSpec = new NCoderMixer::CCoderMixer2ST;
|
||||
_mixerCoder = _mixerCoderSTSpec;
|
||||
_mixerCoderCommon = _mixerCoderSTSpec;
|
||||
#endif
|
||||
}
|
||||
RINOK(_mixerCoderCommon->SetBindInfo(bindInfo));
|
||||
|
||||
for (i = 0; i < numCoders; i++)
|
||||
{
|
||||
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
||||
|
||||
|
||||
CMyComPtr<ICompressCoder> decoder;
|
||||
CMyComPtr<ICompressCoder2> decoder2;
|
||||
RINOK(CreateCoder(
|
||||
EXTERNAL_CODECS_LOC_VARS
|
||||
coderInfo.MethodID, decoder, decoder2, false));
|
||||
CMyComPtr<IUnknown> decoderUnknown;
|
||||
if (coderInfo.IsSimpleCoder())
|
||||
{
|
||||
if (decoder == 0)
|
||||
return E_NOTIMPL;
|
||||
|
||||
decoderUnknown = (IUnknown *)decoder;
|
||||
|
||||
if (_multiThread)
|
||||
_mixerCoderMTSpec->AddCoder(decoder);
|
||||
#ifdef _ST_MODE
|
||||
else
|
||||
_mixerCoderSTSpec->AddCoder(decoder, false);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (decoder2 == 0)
|
||||
return E_NOTIMPL;
|
||||
decoderUnknown = (IUnknown *)decoder2;
|
||||
if (_multiThread)
|
||||
_mixerCoderMTSpec->AddCoder2(decoder2);
|
||||
#ifdef _ST_MODE
|
||||
else
|
||||
_mixerCoderSTSpec->AddCoder2(decoder2, false);
|
||||
#endif
|
||||
}
|
||||
_decoders.Add(decoderUnknown);
|
||||
#ifdef EXTERNAL_CODECS
|
||||
CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
|
||||
decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
|
||||
if (setCompressCodecsInfo)
|
||||
{
|
||||
RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
_bindInfoExPrev = bindInfo;
|
||||
_bindInfoExPrevIsDefined = true;
|
||||
}
|
||||
int i;
|
||||
_mixerCoderCommon->ReInit();
|
||||
|
||||
UInt32 packStreamIndex = 0, unpackStreamIndex = 0;
|
||||
UInt32 coderIndex = 0;
|
||||
// UInt32 coder2Index = 0;
|
||||
|
||||
for (i = 0; i < numCoders; i++)
|
||||
{
|
||||
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
||||
CMyComPtr<IUnknown> &decoder = _decoders[coderIndex];
|
||||
|
||||
{
|
||||
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
|
||||
decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
|
||||
if (setDecoderProperties)
|
||||
{
|
||||
const CByteBuffer &props = coderInfo.Props;
|
||||
size_t size = props.GetCapacity();
|
||||
if (size > 0xFFFFFFFF)
|
||||
return E_NOTIMPL;
|
||||
if (size > 0)
|
||||
{
|
||||
RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
if (mtMode)
|
||||
{
|
||||
CMyComPtr<ICompressSetCoderMt> setCoderMt;
|
||||
decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
|
||||
if (setCoderMt)
|
||||
{
|
||||
RINOK(setCoderMt->SetNumberOfThreads(numThreads));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
{
|
||||
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
||||
decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
|
||||
if (cryptoSetPassword)
|
||||
{
|
||||
if (getTextPassword == 0)
|
||||
return E_FAIL;
|
||||
CMyComBSTR passwordBSTR;
|
||||
RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR));
|
||||
CByteBuffer buffer;
|
||||
passwordIsDefined = true;
|
||||
const UString password(passwordBSTR);
|
||||
const UInt32 sizeInBytes = password.Length() * 2;
|
||||
buffer.SetCapacity(sizeInBytes);
|
||||
for (int i = 0; i < password.Length(); i++)
|
||||
{
|
||||
wchar_t c = password[i];
|
||||
((Byte *)buffer)[i * 2] = (Byte)c;
|
||||
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
||||
}
|
||||
RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
coderIndex++;
|
||||
|
||||
UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;
|
||||
UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;
|
||||
CRecordVector<const UInt64 *> packSizesPointers;
|
||||
CRecordVector<const UInt64 *> unpackSizesPointers;
|
||||
packSizesPointers.Reserve(numInStreams);
|
||||
unpackSizesPointers.Reserve(numOutStreams);
|
||||
UInt32 j;
|
||||
for (j = 0; j < numOutStreams; j++, unpackStreamIndex++)
|
||||
unpackSizesPointers.Add(&folderInfo.UnpackSizes[unpackStreamIndex]);
|
||||
|
||||
for (j = 0; j < numInStreams; j++, packStreamIndex++)
|
||||
{
|
||||
int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
|
||||
if (bindPairIndex >= 0)
|
||||
packSizesPointers.Add(
|
||||
&folderInfo.UnpackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]);
|
||||
else
|
||||
{
|
||||
int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
|
||||
if (index < 0)
|
||||
return E_FAIL;
|
||||
packSizesPointers.Add(&packSizes[index]);
|
||||
}
|
||||
}
|
||||
|
||||
_mixerCoderCommon->SetCoderInfo(i,
|
||||
&packSizesPointers.Front(),
|
||||
&unpackSizesPointers.Front());
|
||||
}
|
||||
UInt32 mainCoder, temp;
|
||||
bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
|
||||
|
||||
if (_multiThread)
|
||||
_mixerCoderMTSpec->SetProgressCoderIndex(mainCoder);
|
||||
/*
|
||||
else
|
||||
_mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);;
|
||||
*/
|
||||
|
||||
if (numCoders == 0)
|
||||
return 0;
|
||||
CRecordVector<ISequentialInStream *> inStreamPointers;
|
||||
inStreamPointers.Reserve(inStreams.Size());
|
||||
for (i = 0; i < inStreams.Size(); i++)
|
||||
inStreamPointers.Add(inStreams[i]);
|
||||
ISequentialOutStream *outStreamPointer = outStream;
|
||||
return _mixerCoder->Code(&inStreamPointers.Front(), NULL,
|
||||
inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress);
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,68 +0,0 @@
|
|||
// 7zDecode.h
|
||||
|
||||
#ifndef __7Z_DECODE_H
|
||||
#define __7Z_DECODE_H
|
||||
|
||||
#include "../../IStream.h"
|
||||
#include "../../IPassword.h"
|
||||
|
||||
#include "../Common/CoderMixer2.h"
|
||||
#include "../Common/CoderMixer2MT.h"
|
||||
#ifdef _ST_MODE
|
||||
#include "../Common/CoderMixer2ST.h"
|
||||
#endif
|
||||
|
||||
#include "../../Common/CreateCoder.h"
|
||||
|
||||
#include "7zItem.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
struct CBindInfoEx: public NCoderMixer::CBindInfo
|
||||
{
|
||||
CRecordVector<CMethodId> CoderMethodIDs;
|
||||
void Clear()
|
||||
{
|
||||
CBindInfo::Clear();
|
||||
CoderMethodIDs.Clear();
|
||||
}
|
||||
};
|
||||
|
||||
class CDecoder
|
||||
{
|
||||
bool _bindInfoExPrevIsDefined;
|
||||
CBindInfoEx _bindInfoExPrev;
|
||||
|
||||
bool _multiThread;
|
||||
#ifdef _ST_MODE
|
||||
NCoderMixer::CCoderMixer2ST *_mixerCoderSTSpec;
|
||||
#endif
|
||||
NCoderMixer::CCoderMixer2MT *_mixerCoderMTSpec;
|
||||
NCoderMixer::CCoderMixer2 *_mixerCoderCommon;
|
||||
|
||||
CMyComPtr<ICompressCoder2> _mixerCoder;
|
||||
CObjectVector<CMyComPtr<IUnknown> > _decoders;
|
||||
// CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2;
|
||||
public:
|
||||
CDecoder(bool multiThread);
|
||||
HRESULT Decode(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
IInStream *inStream,
|
||||
UInt64 startPos,
|
||||
const UInt64 *packSizes,
|
||||
const CFolder &folder,
|
||||
ISequentialOutStream *outStream,
|
||||
ICompressProgressInfo *compressProgress
|
||||
#ifndef _NO_CRYPTO
|
||||
, ICryptoGetTextPassword *getTextPasswordSpec, bool &passwordIsDefined
|
||||
#endif
|
||||
#ifdef COMPRESS_MT
|
||||
, bool mtMode, UInt32 numThreads
|
||||
#endif
|
||||
);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
|
@ -1,273 +0,0 @@
|
|||
// 7zExtract.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zHandler.h"
|
||||
#include "7zFolderOutStream.h"
|
||||
#include "7zDecode.h"
|
||||
// #include "7z1Decode.h"
|
||||
|
||||
#include "../../../Common/ComTry.h"
|
||||
#include "../../Common/StreamObjects.h"
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
struct CExtractFolderInfo
|
||||
{
|
||||
#ifdef _7Z_VOL
|
||||
int VolumeIndex;
|
||||
#endif
|
||||
CNum FileIndex;
|
||||
CNum FolderIndex;
|
||||
CBoolVector ExtractStatuses;
|
||||
UInt64 UnpackSize;
|
||||
CExtractFolderInfo(
|
||||
#ifdef _7Z_VOL
|
||||
int volumeIndex,
|
||||
#endif
|
||||
CNum fileIndex, CNum folderIndex):
|
||||
#ifdef _7Z_VOL
|
||||
VolumeIndex(volumeIndex),
|
||||
#endif
|
||||
FileIndex(fileIndex),
|
||||
FolderIndex(folderIndex),
|
||||
UnpackSize(0)
|
||||
{
|
||||
if (fileIndex != kNumNoIndex)
|
||||
{
|
||||
ExtractStatuses.Reserve(1);
|
||||
ExtractStatuses.Add(true);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool testMode = (testModeSpec != 0);
|
||||
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
||||
UInt64 importantTotalUnpacked = 0;
|
||||
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
if (allFilesMode)
|
||||
numItems =
|
||||
#ifdef _7Z_VOL
|
||||
_refs.Size();
|
||||
#else
|
||||
_db.Files.Size();
|
||||
#endif
|
||||
|
||||
if(numItems == 0)
|
||||
return S_OK;
|
||||
|
||||
/*
|
||||
if(_volumes.Size() != 1)
|
||||
return E_FAIL;
|
||||
const CVolume &volume = _volumes.Front();
|
||||
const CArchiveDatabaseEx &_db = volume.Database;
|
||||
IInStream *_inStream = volume.Stream;
|
||||
*/
|
||||
|
||||
CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
|
||||
for(UInt32 ii = 0; ii < numItems; ii++)
|
||||
{
|
||||
// UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
|
||||
UInt32 ref2Index = allFilesMode ? ii : indices[ii];
|
||||
// const CRef2 &ref2 = _refs[ref2Index];
|
||||
|
||||
// for(UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)
|
||||
{
|
||||
#ifdef _7Z_VOL
|
||||
// const CRef &ref = ref2.Refs[ri];
|
||||
const CRef &ref = _refs[ref2Index];
|
||||
|
||||
int volumeIndex = ref.VolumeIndex;
|
||||
const CVolume &volume = _volumes[volumeIndex];
|
||||
const CArchiveDatabaseEx &db = volume.Database;
|
||||
UInt32 fileIndex = ref.ItemIndex;
|
||||
#else
|
||||
const CArchiveDatabaseEx &db = _db;
|
||||
UInt32 fileIndex = ref2Index;
|
||||
#endif
|
||||
|
||||
CNum folderIndex = db.FileIndexToFolderIndexMap[fileIndex];
|
||||
if (folderIndex == kNumNoIndex)
|
||||
{
|
||||
extractFolderInfoVector.Add(CExtractFolderInfo(
|
||||
#ifdef _7Z_VOL
|
||||
volumeIndex,
|
||||
#endif
|
||||
fileIndex, kNumNoIndex));
|
||||
continue;
|
||||
}
|
||||
if (extractFolderInfoVector.IsEmpty() ||
|
||||
folderIndex != extractFolderInfoVector.Back().FolderIndex
|
||||
#ifdef _7Z_VOL
|
||||
|| volumeIndex != extractFolderInfoVector.Back().VolumeIndex
|
||||
#endif
|
||||
)
|
||||
{
|
||||
extractFolderInfoVector.Add(CExtractFolderInfo(
|
||||
#ifdef _7Z_VOL
|
||||
volumeIndex,
|
||||
#endif
|
||||
kNumNoIndex, folderIndex));
|
||||
const CFolder &folderInfo = db.Folders[folderIndex];
|
||||
UInt64 unpackSize = folderInfo.GetUnpackSize();
|
||||
importantTotalUnpacked += unpackSize;
|
||||
extractFolderInfoVector.Back().UnpackSize = unpackSize;
|
||||
}
|
||||
|
||||
CExtractFolderInfo &efi = extractFolderInfoVector.Back();
|
||||
|
||||
// const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
|
||||
CNum startIndex = db.FolderStartFileIndex[folderIndex];
|
||||
for (CNum index = efi.ExtractStatuses.Size();
|
||||
index <= fileIndex - startIndex; index++)
|
||||
{
|
||||
// UInt64 unpackSize = _db.Files[startIndex + index].UnpackSize;
|
||||
// Count partial_folder_size
|
||||
// efi.UnpackSize += unpackSize;
|
||||
// importantTotalUnpacked += unpackSize;
|
||||
efi.ExtractStatuses.Add(index == fileIndex - startIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extractCallback->SetTotal(importantTotalUnpacked);
|
||||
|
||||
CDecoder decoder(
|
||||
#ifdef _ST_MODE
|
||||
false
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
);
|
||||
// CDecoder1 decoder;
|
||||
|
||||
UInt64 currentTotalPacked = 0;
|
||||
UInt64 currentTotalUnpacked = 0;
|
||||
UInt64 totalFolderUnpacked;
|
||||
UInt64 totalFolderPacked;
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, false);
|
||||
|
||||
for(int i = 0; i < extractFolderInfoVector.Size(); i++,
|
||||
currentTotalUnpacked += totalFolderUnpacked,
|
||||
currentTotalPacked += totalFolderPacked)
|
||||
{
|
||||
lps->OutSize = currentTotalUnpacked;
|
||||
lps->InSize = currentTotalPacked;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
const CExtractFolderInfo &efi = extractFolderInfoVector[i];
|
||||
totalFolderUnpacked = efi.UnpackSize;
|
||||
|
||||
totalFolderPacked = 0;
|
||||
|
||||
CFolderOutStream *folderOutStream = new CFolderOutStream;
|
||||
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
const CVolume &volume = _volumes[efi.VolumeIndex];
|
||||
const CArchiveDatabaseEx &db = volume.Database;
|
||||
#else
|
||||
const CArchiveDatabaseEx &db = _db;
|
||||
#endif
|
||||
|
||||
CNum startIndex;
|
||||
if (efi.FileIndex != kNumNoIndex)
|
||||
startIndex = efi.FileIndex;
|
||||
else
|
||||
startIndex = db.FolderStartFileIndex[efi.FolderIndex];
|
||||
|
||||
|
||||
HRESULT result = folderOutStream->Init(&db,
|
||||
#ifdef _7Z_VOL
|
||||
volume.StartRef2Index,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
startIndex,
|
||||
&efi.ExtractStatuses, extractCallback, testMode, _crcSize != 0);
|
||||
|
||||
RINOK(result);
|
||||
|
||||
if (efi.FileIndex != kNumNoIndex)
|
||||
continue;
|
||||
|
||||
CNum folderIndex = efi.FolderIndex;
|
||||
const CFolder &folderInfo = db.Folders[folderIndex];
|
||||
|
||||
totalFolderPacked = _db.GetFolderFullPackSize(folderIndex);
|
||||
|
||||
CNum packStreamIndex = db.FolderStartPackStreamIndex[folderIndex];
|
||||
UInt64 folderStartPackPos = db.GetFolderStreamPos(folderIndex, 0);
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
||||
if (extractCallback)
|
||||
extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
#ifndef _NO_CRYPTO
|
||||
bool passwordIsDefined;
|
||||
#endif
|
||||
|
||||
HRESULT result = decoder.Decode(
|
||||
EXTERNAL_CODECS_VARS
|
||||
#ifdef _7Z_VOL
|
||||
volume.Stream,
|
||||
#else
|
||||
_inStream,
|
||||
#endif
|
||||
folderStartPackPos,
|
||||
&db.PackSizes[packStreamIndex],
|
||||
folderInfo,
|
||||
outStream,
|
||||
progress
|
||||
#ifndef _NO_CRYPTO
|
||||
, getTextPassword, passwordIsDefined
|
||||
#endif
|
||||
#ifdef COMPRESS_MT
|
||||
, true, _numThreads
|
||||
#endif
|
||||
);
|
||||
|
||||
if (result == S_FALSE)
|
||||
{
|
||||
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
if (result == E_NOTIMPL)
|
||||
{
|
||||
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kUnSupportedMethod));
|
||||
continue;
|
||||
}
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
if (folderOutStream->WasWritingFinished() != S_OK)
|
||||
{
|
||||
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
RINOK(folderOutStream->FlushCorrupted(NArchive::NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,130 +0,0 @@
|
|||
// 7zFolderInStream.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zFolderInStream.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
CFolderInStream::CFolderInStream()
|
||||
{
|
||||
_inStreamWithHashSpec = new CSequentialInStreamWithCRC;
|
||||
_inStreamWithHash = _inStreamWithHashSpec;
|
||||
}
|
||||
|
||||
void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
|
||||
const UInt32 *fileIndices, UInt32 numFiles)
|
||||
{
|
||||
_updateCallback = updateCallback;
|
||||
_numFiles = numFiles;
|
||||
_fileIndex = 0;
|
||||
_fileIndices = fileIndices;
|
||||
Processed.Clear();
|
||||
CRCs.Clear();
|
||||
Sizes.Clear();
|
||||
_fileIsOpen = false;
|
||||
_currentSizeIsDefined = false;
|
||||
}
|
||||
|
||||
HRESULT CFolderInStream::OpenStream()
|
||||
{
|
||||
_filePos = 0;
|
||||
while (_fileIndex < _numFiles)
|
||||
{
|
||||
_currentSizeIsDefined = false;
|
||||
CMyComPtr<ISequentialInStream> stream;
|
||||
HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream);
|
||||
if (result != S_OK && result != S_FALSE)
|
||||
return result;
|
||||
_fileIndex++;
|
||||
_inStreamWithHashSpec->SetStream(stream);
|
||||
_inStreamWithHashSpec->Init();
|
||||
if (!stream)
|
||||
{
|
||||
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
Sizes.Add(0);
|
||||
Processed.Add(result == S_OK);
|
||||
AddDigest();
|
||||
continue;
|
||||
}
|
||||
CMyComPtr<IStreamGetSize> streamGetSize;
|
||||
if (stream.QueryInterface(IID_IStreamGetSize, &streamGetSize) == S_OK)
|
||||
{
|
||||
if(streamGetSize)
|
||||
{
|
||||
_currentSizeIsDefined = true;
|
||||
RINOK(streamGetSize->GetSize(&_currentSize));
|
||||
}
|
||||
}
|
||||
|
||||
_fileIsOpen = true;
|
||||
return S_OK;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CFolderInStream::AddDigest()
|
||||
{
|
||||
CRCs.Add(_inStreamWithHashSpec->GetCRC());
|
||||
}
|
||||
|
||||
HRESULT CFolderInStream::CloseStream()
|
||||
{
|
||||
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||
_inStreamWithHashSpec->ReleaseStream();
|
||||
_fileIsOpen = false;
|
||||
Processed.Add(true);
|
||||
Sizes.Add(_filePos);
|
||||
AddDigest();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 realProcessedSize = 0;
|
||||
while ((_fileIndex < _numFiles || _fileIsOpen) && size > 0)
|
||||
{
|
||||
if (_fileIsOpen)
|
||||
{
|
||||
UInt32 localProcessedSize;
|
||||
RINOK(_inStreamWithHash->Read(
|
||||
((Byte *)data) + realProcessedSize, size, &localProcessedSize));
|
||||
if (localProcessedSize == 0)
|
||||
{
|
||||
RINOK(CloseStream());
|
||||
continue;
|
||||
}
|
||||
realProcessedSize += localProcessedSize;
|
||||
_filePos += localProcessedSize;
|
||||
size -= localProcessedSize;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(OpenStream());
|
||||
}
|
||||
}
|
||||
if (processedSize != 0)
|
||||
*processedSize = realProcessedSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
|
||||
{
|
||||
*value = 0;
|
||||
int subStreamIndex = (int)subStream;
|
||||
if (subStreamIndex < 0 || subStream > Sizes.Size())
|
||||
return E_FAIL;
|
||||
if (subStreamIndex < Sizes.Size())
|
||||
{
|
||||
*value= Sizes[subStreamIndex];
|
||||
return S_OK;
|
||||
}
|
||||
if (!_currentSizeIsDefined)
|
||||
return S_FALSE;
|
||||
*value = _currentSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,66 +0,0 @@
|
|||
// 7z/FolderInStream.h
|
||||
|
||||
#ifndef __7Z_FOLDERINSTREAM_H
|
||||
#define __7Z_FOLDERINSTREAM_H
|
||||
|
||||
#include "7zItem.h"
|
||||
#include "7zHeader.h"
|
||||
|
||||
#include "../IArchive.h"
|
||||
#include "../Common/InStreamWithCRC.h"
|
||||
#include "../../IStream.h"
|
||||
#include "../../ICoder.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
class CFolderInStream:
|
||||
public ISequentialInStream,
|
||||
public ICompressGetSubStreamSize,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
|
||||
|
||||
CFolderInStream();
|
||||
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
|
||||
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
|
||||
private:
|
||||
CSequentialInStreamWithCRC *_inStreamWithHashSpec;
|
||||
CMyComPtr<ISequentialInStream> _inStreamWithHash;
|
||||
CMyComPtr<IArchiveUpdateCallback> _updateCallback;
|
||||
|
||||
bool _currentSizeIsDefined;
|
||||
UInt64 _currentSize;
|
||||
|
||||
bool _fileIsOpen;
|
||||
UInt64 _filePos;
|
||||
|
||||
const UInt32 *_fileIndices;
|
||||
UInt32 _numFiles;
|
||||
UInt32 _fileIndex;
|
||||
|
||||
HRESULT OpenStream();
|
||||
HRESULT CloseStream();
|
||||
void AddDigest();
|
||||
public:
|
||||
void Init(IArchiveUpdateCallback *updateCallback,
|
||||
const UInt32 *fileIndices, UInt32 numFiles);
|
||||
CRecordVector<bool> Processed;
|
||||
CRecordVector<UInt32> CRCs;
|
||||
CRecordVector<UInt64> Sizes;
|
||||
UInt64 GetFullSize() const
|
||||
{
|
||||
UInt64 size = 0;
|
||||
for (int i = 0; i < Sizes.Size(); i++)
|
||||
size += Sizes[i];
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
|
@ -1,164 +0,0 @@
|
|||
// 7zFolderOutStream.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zFolderOutStream.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
CFolderOutStream::CFolderOutStream()
|
||||
{
|
||||
_outStreamWithHashSpec = new COutStreamWithCRC;
|
||||
_outStreamWithHash = _outStreamWithHashSpec;
|
||||
}
|
||||
|
||||
HRESULT CFolderOutStream::Init(
|
||||
const CArchiveDatabaseEx *archiveDatabase,
|
||||
UInt32 ref2Offset,
|
||||
UInt32 startIndex,
|
||||
const CBoolVector *extractStatuses,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
bool testMode,
|
||||
bool checkCrc)
|
||||
{
|
||||
_archiveDatabase = archiveDatabase;
|
||||
_ref2Offset = ref2Offset;
|
||||
_startIndex = startIndex;
|
||||
|
||||
_extractStatuses = extractStatuses;
|
||||
_extractCallback = extractCallback;
|
||||
_testMode = testMode;
|
||||
|
||||
_checkCrc = checkCrc;
|
||||
|
||||
_currentIndex = 0;
|
||||
_fileIsOpen = false;
|
||||
return WriteEmptyFiles();
|
||||
}
|
||||
|
||||
HRESULT CFolderOutStream::OpenFile()
|
||||
{
|
||||
Int32 askMode;
|
||||
if((*_extractStatuses)[_currentIndex])
|
||||
askMode = _testMode ?
|
||||
NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
else
|
||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
|
||||
UInt32 index = _startIndex + _currentIndex;
|
||||
RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));
|
||||
|
||||
_outStreamWithHashSpec->SetStream(realOutStream);
|
||||
_outStreamWithHashSpec->Init(_checkCrc);
|
||||
if (askMode == NArchive::NExtract::NAskMode::kExtract &&
|
||||
(!realOutStream))
|
||||
{
|
||||
const CFileItem &fi = _archiveDatabase->Files[index];
|
||||
if (!_archiveDatabase->IsItemAnti(index) && !fi.IsDir)
|
||||
askMode = NArchive::NExtract::NAskMode::kSkip;
|
||||
}
|
||||
return _extractCallback->PrepareOperation(askMode);
|
||||
}
|
||||
|
||||
HRESULT CFolderOutStream::WriteEmptyFiles()
|
||||
{
|
||||
for(;_currentIndex < _extractStatuses->Size(); _currentIndex++)
|
||||
{
|
||||
UInt32 index = _startIndex + _currentIndex;
|
||||
const CFileItem &fi = _archiveDatabase->Files[index];
|
||||
if (!_archiveDatabase->IsItemAnti(index) && !fi.IsDir && fi.Size != 0)
|
||||
return S_OK;
|
||||
RINOK(OpenFile());
|
||||
RINOK(_extractCallback->SetOperationResult(NArchive::NExtract::NOperationResult::kOK));
|
||||
_outStreamWithHashSpec->ReleaseStream();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFolderOutStream::Write(const void *data,
|
||||
UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 realProcessedSize = 0;
|
||||
while(_currentIndex < _extractStatuses->Size())
|
||||
{
|
||||
if (_fileIsOpen)
|
||||
{
|
||||
UInt32 index = _startIndex + _currentIndex;
|
||||
const CFileItem &fi = _archiveDatabase->Files[index];
|
||||
UInt64 fileSize = fi.Size;
|
||||
|
||||
UInt32 numBytesToWrite = (UInt32)MyMin(fileSize - _filePos,
|
||||
UInt64(size - realProcessedSize));
|
||||
|
||||
UInt32 processedSizeLocal;
|
||||
RINOK(_outStreamWithHash->Write((const Byte *)data + realProcessedSize,
|
||||
numBytesToWrite, &processedSizeLocal));
|
||||
|
||||
_filePos += processedSizeLocal;
|
||||
realProcessedSize += processedSizeLocal;
|
||||
if (_filePos == fileSize)
|
||||
{
|
||||
bool digestsAreEqual;
|
||||
if (fi.CrcDefined && _checkCrc)
|
||||
digestsAreEqual = fi.Crc == _outStreamWithHashSpec->GetCRC();
|
||||
else
|
||||
digestsAreEqual = true;
|
||||
|
||||
RINOK(_extractCallback->SetOperationResult(
|
||||
digestsAreEqual ?
|
||||
NArchive::NExtract::NOperationResult::kOK :
|
||||
NArchive::NExtract::NOperationResult::kCRCError));
|
||||
_outStreamWithHashSpec->ReleaseStream();
|
||||
_fileIsOpen = false;
|
||||
_currentIndex++;
|
||||
}
|
||||
if (realProcessedSize == size)
|
||||
{
|
||||
if (processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
return WriteEmptyFiles();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(OpenFile());
|
||||
_fileIsOpen = true;
|
||||
_filePos = 0;
|
||||
}
|
||||
}
|
||||
if (processedSize != NULL)
|
||||
*processedSize = size;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
|
||||
{
|
||||
while(_currentIndex < _extractStatuses->Size())
|
||||
{
|
||||
if (_fileIsOpen)
|
||||
{
|
||||
RINOK(_extractCallback->SetOperationResult(resultEOperationResult));
|
||||
_outStreamWithHashSpec->ReleaseStream();
|
||||
_fileIsOpen = false;
|
||||
_currentIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(OpenFile());
|
||||
_fileIsOpen = true;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CFolderOutStream::WasWritingFinished()
|
||||
{
|
||||
if (_currentIndex == _extractStatuses->Size())
|
||||
return S_OK;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,60 +0,0 @@
|
|||
// 7zFolderOutStream.h
|
||||
|
||||
#ifndef __7Z_FOLDEROUTSTREAM_H
|
||||
#define __7Z_FOLDEROUTSTREAM_H
|
||||
|
||||
#include "7zIn.h"
|
||||
|
||||
#include "../../IStream.h"
|
||||
#include "../IArchive.h"
|
||||
#include "../Common/OutStreamWithCRC.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
class CFolderOutStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
CFolderOutStream();
|
||||
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
private:
|
||||
|
||||
COutStreamWithCRC *_outStreamWithHashSpec;
|
||||
CMyComPtr<ISequentialOutStream> _outStreamWithHash;
|
||||
const CArchiveDatabaseEx *_archiveDatabase;
|
||||
const CBoolVector *_extractStatuses;
|
||||
UInt32 _startIndex;
|
||||
UInt32 _ref2Offset;
|
||||
int _currentIndex;
|
||||
// UInt64 _currentDataPos;
|
||||
CMyComPtr<IArchiveExtractCallback> _extractCallback;
|
||||
bool _testMode;
|
||||
|
||||
bool _fileIsOpen;
|
||||
|
||||
bool _checkCrc;
|
||||
UInt64 _filePos;
|
||||
|
||||
HRESULT OpenFile();
|
||||
HRESULT WriteEmptyFiles();
|
||||
public:
|
||||
HRESULT Init(
|
||||
const CArchiveDatabaseEx *archiveDatabase,
|
||||
UInt32 ref2Offset,
|
||||
UInt32 startIndex,
|
||||
const CBoolVector *extractStatuses,
|
||||
IArchiveExtractCallback *extractCallback,
|
||||
bool testMode,
|
||||
bool checkCrc);
|
||||
HRESULT FlushCorrupted(Int32 resultEOperationResult);
|
||||
HRESULT WasWritingFinished();
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
|
@ -1,503 +0,0 @@
|
|||
// 7zHandler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/CpuArch.h"
|
||||
}
|
||||
|
||||
#include "../../../Common/ComTry.h"
|
||||
#include "../../../Common/IntToString.h"
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
#include "../../../Windows/System.h"
|
||||
#endif
|
||||
|
||||
#include "../Common/ItemNameUtils.h"
|
||||
|
||||
#include "7zHandler.h"
|
||||
#include "7zProperties.h"
|
||||
|
||||
#ifdef __7Z_SET_PROPERTIES
|
||||
#ifdef EXTRACT_ONLY
|
||||
#include "../Common/ParseProperties.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
extern UString ConvertMethodIdToString(UInt64 id);
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
CHandler::CHandler()
|
||||
{
|
||||
_crcSize = 4;
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
_passwordIsDefined = false;
|
||||
#endif
|
||||
|
||||
#ifdef EXTRACT_ONLY
|
||||
#ifdef COMPRESS_MT
|
||||
_numThreads = NSystem::GetNumberOfProcessors();
|
||||
#endif
|
||||
#else
|
||||
Init();
|
||||
#endif
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
*numItems = _db.Files.Size();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifdef _SFX
|
||||
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
|
||||
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
STATPROPSTG kArcProps[] =
|
||||
{
|
||||
{ NULL, kpidMethod, VT_BSTR},
|
||||
{ NULL, kpidSolid, VT_BOOL},
|
||||
{ NULL, kpidNumBlocks, VT_UI4},
|
||||
{ NULL, kpidPhySize, VT_UI8},
|
||||
{ NULL, kpidHeadersSize, VT_UI8},
|
||||
{ NULL, kpidOffset, VT_UI8}
|
||||
};
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidMethod:
|
||||
{
|
||||
UString resString;
|
||||
CRecordVector<UInt64> ids;
|
||||
int i;
|
||||
for (i = 0; i < _db.Folders.Size(); i++)
|
||||
{
|
||||
const CFolder &f = _db.Folders[i];
|
||||
for (int j = f.Coders.Size() - 1; j >= 0; j--)
|
||||
ids.AddToUniqueSorted(f.Coders[j].MethodID);
|
||||
}
|
||||
|
||||
for (i = 0; i < ids.Size(); i++)
|
||||
{
|
||||
UInt64 id = ids[i];
|
||||
UString methodName;
|
||||
/* bool methodIsKnown = */ FindMethod(EXTERNAL_CODECS_VARS id, methodName);
|
||||
if (methodName.IsEmpty())
|
||||
methodName = ConvertMethodIdToString(id);
|
||||
if (!resString.IsEmpty())
|
||||
resString += L' ';
|
||||
resString += methodName;
|
||||
}
|
||||
prop = resString;
|
||||
break;
|
||||
}
|
||||
case kpidSolid: prop = _db.IsSolid(); 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);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
#endif
|
||||
|
||||
static void SetPropFromUInt64Def(CUInt64DefVector &v, int index, NCOM::CPropVariant &prop)
|
||||
{
|
||||
UInt64 value;
|
||||
if (v.GetItem(index, value))
|
||||
{
|
||||
FILETIME ft;
|
||||
ft.dwLowDateTime = (DWORD)value;
|
||||
ft.dwHighDateTime = (DWORD)(value >> 32);
|
||||
prop = ft;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _SFX
|
||||
|
||||
static UString ConvertUInt32ToString(UInt32 value)
|
||||
{
|
||||
wchar_t buffer[32];
|
||||
ConvertUInt64ToString(value, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static UString GetStringForSizeValue(UInt32 value)
|
||||
{
|
||||
for (int i = 31; i >= 0; i--)
|
||||
if ((UInt32(1) << i) == value)
|
||||
return ConvertUInt32ToString(i);
|
||||
UString result;
|
||||
if (value % (1 << 20) == 0)
|
||||
{
|
||||
result += ConvertUInt32ToString(value >> 20);
|
||||
result += L"m";
|
||||
}
|
||||
else if (value % (1 << 10) == 0)
|
||||
{
|
||||
result += ConvertUInt32ToString(value >> 10);
|
||||
result += L"k";
|
||||
}
|
||||
else
|
||||
{
|
||||
result += ConvertUInt32ToString(value);
|
||||
result += L"b";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static const UInt64 k_Copy = 0x0;
|
||||
static const UInt64 k_LZMA = 0x030101;
|
||||
static const UInt64 k_PPMD = 0x030401;
|
||||
|
||||
static wchar_t GetHex(Byte value)
|
||||
{
|
||||
return (wchar_t)((value < 10) ? (L'0' + value) : (L'A' + (value - 10)));
|
||||
}
|
||||
static inline UString GetHex2(Byte value)
|
||||
{
|
||||
UString result;
|
||||
result += GetHex((Byte)(value >> 4));
|
||||
result += GetHex((Byte)(value & 0xF));
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static const UInt64 k_AES = 0x06F10701;
|
||||
|
||||
bool CHandler::IsEncrypted(UInt32 index2) const
|
||||
{
|
||||
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
{
|
||||
const CFolder &folderInfo = _db.Folders[folderIndex];
|
||||
for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
|
||||
if (folderInfo.Coders[i].MethodID == k_AES)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NCOM::CPropVariant prop;
|
||||
|
||||
/*
|
||||
const CRef2 &ref2 = _refs[index];
|
||||
if (ref2.Refs.IsEmpty())
|
||||
return E_FAIL;
|
||||
const CRef &ref = ref2.Refs.Front();
|
||||
*/
|
||||
|
||||
const CFileItem &item = _db.Files[index];
|
||||
UInt32 index2 = index;
|
||||
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
if (!item.Name.IsEmpty())
|
||||
prop = NItemName::GetOSName(item.Name);
|
||||
break;
|
||||
case kpidIsDir: prop = item.IsDir; break;
|
||||
case kpidSize:
|
||||
{
|
||||
prop = item.Size;
|
||||
// prop = ref2.Size;
|
||||
break;
|
||||
}
|
||||
case kpidPackSize:
|
||||
{
|
||||
// prop = ref2.PackSize;
|
||||
{
|
||||
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
{
|
||||
if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2)
|
||||
prop = _db.GetFolderFullPackSize(folderIndex);
|
||||
/*
|
||||
else
|
||||
prop = (UInt64)0;
|
||||
*/
|
||||
}
|
||||
else
|
||||
prop = (UInt64)0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) prop = v; break; }
|
||||
case kpidCTime: SetPropFromUInt64Def(_db.CTime, index2, prop); break;
|
||||
case kpidATime: SetPropFromUInt64Def(_db.ATime, index2, prop); break;
|
||||
case kpidMTime: SetPropFromUInt64Def(_db.MTime, index2, prop); break;
|
||||
case kpidAttrib: if (item.AttribDefined) prop = item.Attrib; break;
|
||||
case kpidCRC: if (item.CrcDefined) prop = item.Crc; break;
|
||||
case kpidEncrypted: prop = IsEncrypted(index2); break;
|
||||
case kpidIsAnti: prop = _db.IsItemAnti(index2); break;
|
||||
#ifndef _SFX
|
||||
case kpidMethod:
|
||||
{
|
||||
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
{
|
||||
const CFolder &folderInfo = _db.Folders[folderIndex];
|
||||
UString methodsString;
|
||||
for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
||||
if (!methodsString.IsEmpty())
|
||||
methodsString += L' ';
|
||||
|
||||
{
|
||||
UString methodName;
|
||||
bool methodIsKnown = FindMethod(
|
||||
EXTERNAL_CODECS_VARS
|
||||
coderInfo.MethodID, methodName);
|
||||
|
||||
if (methodIsKnown)
|
||||
{
|
||||
methodsString += methodName;
|
||||
if (coderInfo.MethodID == k_LZMA)
|
||||
{
|
||||
if (coderInfo.Props.GetCapacity() >= 5)
|
||||
{
|
||||
methodsString += L":";
|
||||
UInt32 dicSize = GetUi32((const Byte *)coderInfo.Props + 1);
|
||||
methodsString += GetStringForSizeValue(dicSize);
|
||||
}
|
||||
}
|
||||
else if (coderInfo.MethodID == k_PPMD)
|
||||
{
|
||||
if (coderInfo.Props.GetCapacity() >= 5)
|
||||
{
|
||||
Byte order = *(const Byte *)coderInfo.Props;
|
||||
methodsString += L":o";
|
||||
methodsString += ConvertUInt32ToString(order);
|
||||
methodsString += L":mem";
|
||||
UInt32 dicSize = GetUi32((const Byte *)coderInfo.Props + 1);
|
||||
methodsString += GetStringForSizeValue(dicSize);
|
||||
}
|
||||
}
|
||||
else if (coderInfo.MethodID == k_AES)
|
||||
{
|
||||
if (coderInfo.Props.GetCapacity() >= 1)
|
||||
{
|
||||
methodsString += L":";
|
||||
const Byte *data = (const Byte *)coderInfo.Props;
|
||||
Byte firstByte = *data++;
|
||||
UInt32 numCyclesPower = firstByte & 0x3F;
|
||||
methodsString += ConvertUInt32ToString(numCyclesPower);
|
||||
/*
|
||||
if ((firstByte & 0xC0) != 0)
|
||||
{
|
||||
methodsString += L":";
|
||||
return S_OK;
|
||||
UInt32 saltSize = (firstByte >> 7) & 1;
|
||||
UInt32 ivSize = (firstByte >> 6) & 1;
|
||||
if (coderInfo.Props.GetCapacity() >= 2)
|
||||
{
|
||||
Byte secondByte = *data++;
|
||||
saltSize += (secondByte >> 4);
|
||||
ivSize += (secondByte & 0x0F);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (coderInfo.Props.GetCapacity() > 0)
|
||||
{
|
||||
methodsString += L":[";
|
||||
for (size_t bi = 0; bi < coderInfo.Props.GetCapacity(); bi++)
|
||||
{
|
||||
if (bi > 5 && bi + 1 < coderInfo.Props.GetCapacity())
|
||||
{
|
||||
methodsString += L"..";
|
||||
break;
|
||||
}
|
||||
else
|
||||
methodsString += GetHex2(coderInfo.Props[bi]);
|
||||
}
|
||||
methodsString += L"]";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
methodsString += ConvertMethodIdToString(coderInfo.MethodID);
|
||||
}
|
||||
}
|
||||
}
|
||||
prop = methodsString;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kpidBlock:
|
||||
{
|
||||
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
prop = (UInt32)folderIndex;
|
||||
}
|
||||
break;
|
||||
case kpidPackedSize0:
|
||||
case kpidPackedSize1:
|
||||
case kpidPackedSize2:
|
||||
case kpidPackedSize3:
|
||||
case kpidPackedSize4:
|
||||
{
|
||||
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
{
|
||||
const CFolder &folderInfo = _db.Folders[folderIndex];
|
||||
if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
|
||||
folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
|
||||
{
|
||||
prop = _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
|
||||
}
|
||||
else
|
||||
prop = (UInt64)0;
|
||||
}
|
||||
else
|
||||
prop = (UInt64)0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
const UInt64 *maxCheckStartPosition,
|
||||
IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
Close();
|
||||
#ifndef _SFX
|
||||
_fileInfoPopIDs.Clear();
|
||||
#endif
|
||||
try
|
||||
{
|
||||
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
||||
if (openArchiveCallback)
|
||||
{
|
||||
openArchiveCallbackTemp.QueryInterface(
|
||||
IID_ICryptoGetTextPassword, &getTextPassword);
|
||||
}
|
||||
#endif
|
||||
CInArchive archive;
|
||||
RINOK(archive.Open(stream, maxCheckStartPosition));
|
||||
#ifndef _NO_CRYPTO
|
||||
_passwordIsDefined = false;
|
||||
UString password;
|
||||
#endif
|
||||
HRESULT result = archive.ReadDatabase(
|
||||
EXTERNAL_CODECS_VARS
|
||||
_db
|
||||
#ifndef _NO_CRYPTO
|
||||
, getTextPassword, _passwordIsDefined
|
||||
#endif
|
||||
);
|
||||
RINOK(result);
|
||||
_db.Fill();
|
||||
_inStream = stream;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
Close();
|
||||
return S_FALSE;
|
||||
}
|
||||
// _inStream = stream;
|
||||
#ifndef _SFX
|
||||
FillPopIDs();
|
||||
#endif
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
_inStream.Release();
|
||||
_db.Clear();
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
#ifdef __7Z_SET_PROPERTIES
|
||||
#ifdef EXTRACT_ONLY
|
||||
|
||||
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
#ifdef COMPRESS_MT
|
||||
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
|
||||
_numThreads = numProcessors;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < numProperties; i++)
|
||||
{
|
||||
UString name = names[i];
|
||||
name.MakeUpper();
|
||||
if (name.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
const PROPVARIANT &value = values[i];
|
||||
UInt32 number;
|
||||
int index = ParseStringToUInt32(name, number);
|
||||
if (index == 0)
|
||||
{
|
||||
if(name.Left(2).CompareNoCase(L"MT") == 0)
|
||||
{
|
||||
#ifdef COMPRESS_MT
|
||||
RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
IMPL_ISetCompressCodecsInfo
|
||||
|
||||
}}
|
|
@ -1,121 +0,0 @@
|
|||
// 7z/Handler.h
|
||||
|
||||
#ifndef __7Z_HANDLER_H
|
||||
#define __7Z_HANDLER_H
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../IArchive.h"
|
||||
#include "7zIn.h"
|
||||
|
||||
#include "7zCompressionMode.h"
|
||||
|
||||
#include "../../Common/CreateCoder.h"
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
#include "../Common/HandlerOut.h"
|
||||
#endif
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
#ifndef __7Z_SET_PROPERTIES
|
||||
|
||||
#ifdef EXTRACT_ONLY
|
||||
#ifdef COMPRESS_MT
|
||||
#define __7Z_SET_PROPERTIES
|
||||
#endif
|
||||
#else
|
||||
#define __7Z_SET_PROPERTIES
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
class CHandler:
|
||||
#ifndef EXTRACT_ONLY
|
||||
public NArchive::COutHandler,
|
||||
#endif
|
||||
public IInArchive,
|
||||
#ifdef __7Z_SET_PROPERTIES
|
||||
public ISetProperties,
|
||||
#endif
|
||||
#ifndef EXTRACT_ONLY
|
||||
public IOutArchive,
|
||||
#endif
|
||||
PUBLIC_ISetCompressCodecsInfo
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_QUERYINTERFACE_BEGIN2(IInArchive)
|
||||
#ifdef __7Z_SET_PROPERTIES
|
||||
MY_QUERYINTERFACE_ENTRY(ISetProperties)
|
||||
#endif
|
||||
#ifndef EXTRACT_ONLY
|
||||
MY_QUERYINTERFACE_ENTRY(IOutArchive)
|
||||
#endif
|
||||
QUERY_ENTRY_ISetCompressCodecsInfo
|
||||
MY_QUERYINTERFACE_END
|
||||
MY_ADDREF_RELEASE
|
||||
|
||||
INTERFACE_IInArchive(;)
|
||||
|
||||
#ifdef __7Z_SET_PROPERTIES
|
||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
|
||||
#endif
|
||||
|
||||
#ifndef EXTRACT_ONLY
|
||||
INTERFACE_IOutArchive(;)
|
||||
#endif
|
||||
|
||||
DECL_ISetCompressCodecsInfo
|
||||
|
||||
CHandler();
|
||||
|
||||
private:
|
||||
CMyComPtr<IInStream> _inStream;
|
||||
NArchive::N7z::CArchiveDatabaseEx _db;
|
||||
#ifndef _NO_CRYPTO
|
||||
bool _passwordIsDefined;
|
||||
#endif
|
||||
|
||||
#ifdef EXTRACT_ONLY
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
UInt32 _numThreads;
|
||||
#endif
|
||||
|
||||
UInt32 _crcSize;
|
||||
|
||||
#else
|
||||
|
||||
CRecordVector<CBind> _binds;
|
||||
|
||||
HRESULT SetPassword(CCompressionMethodMode &methodMode, IArchiveUpdateCallback *updateCallback);
|
||||
|
||||
HRESULT SetCompressionMethod(CCompressionMethodMode &method,
|
||||
CObjectVector<COneMethodInfo> &methodsInfo
|
||||
#ifdef COMPRESS_MT
|
||||
, UInt32 numThreads
|
||||
#endif
|
||||
);
|
||||
|
||||
HRESULT SetCompressionMethod(
|
||||
CCompressionMethodMode &method,
|
||||
CCompressionMethodMode &headerMethod);
|
||||
|
||||
#endif
|
||||
|
||||
bool IsEncrypted(UInt32 index2) const;
|
||||
#ifndef _SFX
|
||||
|
||||
CRecordVector<UInt64> _fileInfoPopIDs;
|
||||
void FillPopIDs();
|
||||
|
||||
#endif
|
||||
|
||||
DECL_EXTERNAL_CODECS_VARS
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
|
@ -1,27 +0,0 @@
|
|||
// 7z/Header.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "7zHeader.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
Byte kSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
||||
#ifdef _7Z_VOL
|
||||
Byte kFinishSignature[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C + 1};
|
||||
#endif
|
||||
|
||||
class SignatureInitializer
|
||||
{
|
||||
public:
|
||||
SignatureInitializer()
|
||||
{
|
||||
kSignature[0]--;
|
||||
#ifdef _7Z_VOL
|
||||
kFinishSignature[0]--;
|
||||
#endif
|
||||
};
|
||||
} g_SignatureInitializer;
|
||||
|
||||
}}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
// 7z/7zHeader.h
|
||||
|
||||
#ifndef __7Z_HEADER_H
|
||||
#define __7Z_HEADER_H
|
||||
|
||||
#include "../../../Common/Types.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
const int kSignatureSize = 6;
|
||||
extern Byte kSignature[kSignatureSize];
|
||||
|
||||
// #define _7Z_VOL
|
||||
// 7z-MultiVolume is not finished yet.
|
||||
// It can work already, but I still do not like some
|
||||
// things of that new multivolume format.
|
||||
// So please keep it commented.
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
extern Byte kFinishSignature[kSignatureSize];
|
||||
#endif
|
||||
|
||||
struct CArchiveVersion
|
||||
{
|
||||
Byte Major;
|
||||
Byte Minor;
|
||||
};
|
||||
|
||||
const Byte kMajorVersion = 0;
|
||||
|
||||
struct CStartHeader
|
||||
{
|
||||
UInt64 NextHeaderOffset;
|
||||
UInt64 NextHeaderSize;
|
||||
UInt32 NextHeaderCRC;
|
||||
};
|
||||
|
||||
const UInt32 kStartHeaderSize = 20;
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
struct CFinishHeader: public CStartHeader
|
||||
{
|
||||
UInt64 ArchiveStartOffset; // data offset from end if that struct
|
||||
UInt64 AdditionalStartBlockSize; // start signature & start header size
|
||||
};
|
||||
|
||||
const UInt32 kFinishHeaderSize = kStartHeaderSize + 16;
|
||||
#endif
|
||||
|
||||
namespace NID
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kEnd,
|
||||
|
||||
kHeader,
|
||||
|
||||
kArchiveProperties,
|
||||
|
||||
kAdditionalStreamsInfo,
|
||||
kMainStreamsInfo,
|
||||
kFilesInfo,
|
||||
|
||||
kPackInfo,
|
||||
kUnpackInfo,
|
||||
kSubStreamsInfo,
|
||||
|
||||
kSize,
|
||||
kCRC,
|
||||
|
||||
kFolder,
|
||||
|
||||
kCodersUnpackSize,
|
||||
kNumUnpackStream,
|
||||
|
||||
kEmptyStream,
|
||||
kEmptyFile,
|
||||
kAnti,
|
||||
|
||||
kName,
|
||||
kCTime,
|
||||
kATime,
|
||||
kMTime,
|
||||
kWinAttributes,
|
||||
kComment,
|
||||
|
||||
kEncodedHeader,
|
||||
|
||||
kStartPos,
|
||||
kDummy
|
||||
};
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,245 +0,0 @@
|
|||
// 7zIn.h
|
||||
|
||||
#ifndef __7Z_IN_H
|
||||
#define __7Z_IN_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "../../IPassword.h"
|
||||
#include "../../IStream.h"
|
||||
|
||||
#include "../../Common/CreateCoder.h"
|
||||
#include "../../Common/InBuffer.h"
|
||||
|
||||
#include "7zItem.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
struct CInArchiveInfo
|
||||
{
|
||||
CArchiveVersion Version;
|
||||
UInt64 StartPosition;
|
||||
UInt64 StartPositionAfterHeader;
|
||||
UInt64 DataStartPosition;
|
||||
UInt64 DataStartPosition2;
|
||||
CRecordVector<UInt64> FileInfoPopIDs;
|
||||
void Clear()
|
||||
{
|
||||
FileInfoPopIDs.Clear();
|
||||
}
|
||||
};
|
||||
|
||||
struct CArchiveDatabaseEx: public CArchiveDatabase
|
||||
{
|
||||
CInArchiveInfo ArchiveInfo;
|
||||
CRecordVector<UInt64> PackStreamStartPositions;
|
||||
CRecordVector<CNum> FolderStartPackStreamIndex;
|
||||
CRecordVector<CNum> FolderStartFileIndex;
|
||||
CRecordVector<CNum> FileIndexToFolderIndexMap;
|
||||
|
||||
UInt64 HeadersSize;
|
||||
UInt64 PhySize;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
CArchiveDatabase::Clear();
|
||||
ArchiveInfo.Clear();
|
||||
PackStreamStartPositions.Clear();
|
||||
FolderStartPackStreamIndex.Clear();
|
||||
FolderStartFileIndex.Clear();
|
||||
FileIndexToFolderIndexMap.Clear();
|
||||
|
||||
HeadersSize = 0;
|
||||
PhySize = 0;
|
||||
}
|
||||
|
||||
void FillFolderStartPackStream();
|
||||
void FillStartPos();
|
||||
void FillFolderStartFileIndex();
|
||||
|
||||
void Fill()
|
||||
{
|
||||
FillFolderStartPackStream();
|
||||
FillStartPos();
|
||||
FillFolderStartFileIndex();
|
||||
}
|
||||
|
||||
UInt64 GetFolderStreamPos(int folderIndex, int indexInFolder) const
|
||||
{
|
||||
return ArchiveInfo.DataStartPosition +
|
||||
PackStreamStartPositions[FolderStartPackStreamIndex[folderIndex] + indexInFolder];
|
||||
}
|
||||
|
||||
UInt64 GetFolderFullPackSize(int folderIndex) const
|
||||
{
|
||||
CNum packStreamIndex = FolderStartPackStreamIndex[folderIndex];
|
||||
const CFolder &folder = Folders[folderIndex];
|
||||
UInt64 size = 0;
|
||||
for (int i = 0; i < folder.PackStreams.Size(); i++)
|
||||
size += PackSizes[packStreamIndex + i];
|
||||
return size;
|
||||
}
|
||||
|
||||
UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
|
||||
{
|
||||
return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
|
||||
}
|
||||
|
||||
UInt64 GetFilePackSize(CNum fileIndex) const
|
||||
{
|
||||
CNum folderIndex = FileIndexToFolderIndexMap[fileIndex];
|
||||
if (folderIndex != kNumNoIndex)
|
||||
if (FolderStartFileIndex[folderIndex] == fileIndex)
|
||||
return GetFolderFullPackSize(folderIndex);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
class CInByte2
|
||||
{
|
||||
const Byte *_buffer;
|
||||
size_t _size;
|
||||
public:
|
||||
size_t _pos;
|
||||
void Init(const Byte *buffer, size_t size)
|
||||
{
|
||||
_buffer = buffer;
|
||||
_size = size;
|
||||
_pos = 0;
|
||||
}
|
||||
Byte ReadByte();
|
||||
void ReadBytes(Byte *data, size_t size);
|
||||
void SkeepData(UInt64 size);
|
||||
void SkeepData();
|
||||
UInt64 ReadNumber();
|
||||
CNum ReadNum();
|
||||
UInt32 ReadUInt32();
|
||||
UInt64 ReadUInt64();
|
||||
void ReadString(UString &s);
|
||||
};
|
||||
|
||||
class CStreamSwitch;
|
||||
|
||||
const UInt32 kHeaderSize = 32;
|
||||
|
||||
class CInArchive
|
||||
{
|
||||
friend class CStreamSwitch;
|
||||
|
||||
CMyComPtr<IInStream> _stream;
|
||||
|
||||
CObjectVector<CInByte2> _inByteVector;
|
||||
CInByte2 *_inByteBack;
|
||||
|
||||
UInt64 _arhiveBeginStreamPosition;
|
||||
|
||||
Byte _header[kHeaderSize];
|
||||
|
||||
UInt64 HeadersSize;
|
||||
|
||||
void AddByteStream(const Byte *buffer, size_t size)
|
||||
{
|
||||
_inByteVector.Add(CInByte2());
|
||||
_inByteBack = &_inByteVector.Back();
|
||||
_inByteBack->Init(buffer, size);
|
||||
}
|
||||
|
||||
void DeleteByteStream()
|
||||
{
|
||||
_inByteVector.DeleteBack();
|
||||
if (!_inByteVector.IsEmpty())
|
||||
_inByteBack = &_inByteVector.Back();
|
||||
}
|
||||
|
||||
private:
|
||||
HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
|
||||
|
||||
void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); }
|
||||
Byte ReadByte() { return _inByteBack->ReadByte(); }
|
||||
UInt64 ReadNumber() { return _inByteBack->ReadNumber(); }
|
||||
CNum ReadNum() { return _inByteBack->ReadNum(); }
|
||||
UInt64 ReadID() { return _inByteBack->ReadNumber(); }
|
||||
UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); }
|
||||
UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); }
|
||||
void SkeepData(UInt64 size) { _inByteBack->SkeepData(size); }
|
||||
void SkeepData() { _inByteBack->SkeepData(); }
|
||||
void WaitAttribute(UInt64 attribute);
|
||||
|
||||
void ReadArchiveProperties(CInArchiveInfo &archiveInfo);
|
||||
void GetNextFolderItem(CFolder &itemInfo);
|
||||
void ReadHashDigests(int numItems,
|
||||
CBoolVector &digestsDefined, CRecordVector<UInt32> &digests);
|
||||
|
||||
void ReadPackInfo(
|
||||
UInt64 &dataOffset,
|
||||
CRecordVector<UInt64> &packSizes,
|
||||
CBoolVector &packCRCsDefined,
|
||||
CRecordVector<UInt32> &packCRCs);
|
||||
|
||||
void ReadUnpackInfo(
|
||||
const CObjectVector<CByteBuffer> *dataVector,
|
||||
CObjectVector<CFolder> &folders);
|
||||
|
||||
void ReadSubStreamsInfo(
|
||||
const CObjectVector<CFolder> &folders,
|
||||
CRecordVector<CNum> &numUnpackStreamsInFolders,
|
||||
CRecordVector<UInt64> &unpackSizes,
|
||||
CBoolVector &digestsDefined,
|
||||
CRecordVector<UInt32> &digests);
|
||||
|
||||
void ReadStreamsInfo(
|
||||
const CObjectVector<CByteBuffer> *dataVector,
|
||||
UInt64 &dataOffset,
|
||||
CRecordVector<UInt64> &packSizes,
|
||||
CBoolVector &packCRCsDefined,
|
||||
CRecordVector<UInt32> &packCRCs,
|
||||
CObjectVector<CFolder> &folders,
|
||||
CRecordVector<CNum> &numUnpackStreamsInFolders,
|
||||
CRecordVector<UInt64> &unpackSizes,
|
||||
CBoolVector &digestsDefined,
|
||||
CRecordVector<UInt32> &digests);
|
||||
|
||||
|
||||
void ReadBoolVector(int numItems, CBoolVector &v);
|
||||
void ReadBoolVector2(int numItems, CBoolVector &v);
|
||||
void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
|
||||
CUInt64DefVector &v, int numFiles);
|
||||
HRESULT ReadAndDecodePackedStreams(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
UInt64 baseOffset, UInt64 &dataOffset,
|
||||
CObjectVector<CByteBuffer> &dataVector
|
||||
#ifndef _NO_CRYPTO
|
||||
, ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||
#endif
|
||||
);
|
||||
HRESULT ReadHeader(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
CArchiveDatabaseEx &db
|
||||
#ifndef _NO_CRYPTO
|
||||
,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||
#endif
|
||||
);
|
||||
HRESULT ReadDatabase2(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
CArchiveDatabaseEx &db
|
||||
#ifndef _NO_CRYPTO
|
||||
,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||
#endif
|
||||
);
|
||||
public:
|
||||
HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
|
||||
void Close();
|
||||
|
||||
HRESULT ReadDatabase(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
CArchiveDatabaseEx &db
|
||||
#ifndef _NO_CRYPTO
|
||||
,ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
|
||||
#endif
|
||||
);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
|
@ -1,258 +0,0 @@
|
|||
// 7zItem.h
|
||||
|
||||
#ifndef __7Z_ITEM_H
|
||||
#define __7Z_ITEM_H
|
||||
|
||||
#include "../../../Common/Buffer.h"
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
#include "../../Common/MethodId.h"
|
||||
|
||||
#include "7zHeader.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
typedef UInt32 CNum;
|
||||
const CNum kNumMax = 0x7FFFFFFF;
|
||||
const CNum kNumNoIndex = 0xFFFFFFFF;
|
||||
|
||||
struct CCoderInfo
|
||||
{
|
||||
CMethodId MethodID;
|
||||
CByteBuffer Props;
|
||||
CNum NumInStreams;
|
||||
CNum NumOutStreams;
|
||||
bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
|
||||
};
|
||||
|
||||
struct CBindPair
|
||||
{
|
||||
CNum InIndex;
|
||||
CNum OutIndex;
|
||||
};
|
||||
|
||||
struct CFolder
|
||||
{
|
||||
CObjectVector<CCoderInfo> Coders;
|
||||
CRecordVector<CBindPair> BindPairs;
|
||||
CRecordVector<CNum> PackStreams;
|
||||
CRecordVector<UInt64> UnpackSizes;
|
||||
UInt32 UnpackCRC;
|
||||
bool UnpackCRCDefined;
|
||||
|
||||
CFolder(): UnpackCRCDefined(false) {}
|
||||
|
||||
UInt64 GetUnpackSize() const // test it
|
||||
{
|
||||
if (UnpackSizes.IsEmpty())
|
||||
return 0;
|
||||
for (int i = UnpackSizes.Size() - 1; i >= 0; i--)
|
||||
if (FindBindPairForOutStream(i) < 0)
|
||||
return UnpackSizes[i];
|
||||
throw 1;
|
||||
}
|
||||
|
||||
CNum GetNumOutStreams() const
|
||||
{
|
||||
CNum result = 0;
|
||||
for (int i = 0; i < Coders.Size(); i++)
|
||||
result += Coders[i].NumOutStreams;
|
||||
return result;
|
||||
}
|
||||
|
||||
int FindBindPairForInStream(CNum inStreamIndex) const
|
||||
{
|
||||
for(int i = 0; i < BindPairs.Size(); i++)
|
||||
if (BindPairs[i].InIndex == inStreamIndex)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
int FindBindPairForOutStream(CNum outStreamIndex) const
|
||||
{
|
||||
for(int i = 0; i < BindPairs.Size(); i++)
|
||||
if (BindPairs[i].OutIndex == outStreamIndex)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
int FindPackStreamArrayIndex(CNum inStreamIndex) const
|
||||
{
|
||||
for(int i = 0; i < PackStreams.Size(); i++)
|
||||
if (PackStreams[i] == inStreamIndex)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool CheckStructure() const;
|
||||
};
|
||||
|
||||
struct CUInt64DefVector
|
||||
{
|
||||
CRecordVector<UInt64> Values;
|
||||
CRecordVector<bool> Defined;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Values.Clear();
|
||||
Defined.Clear();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
bool HasStream; // Test it !!! it means that there is
|
||||
// stream in some folder. It can be empty stream
|
||||
bool IsDir;
|
||||
bool CrcDefined;
|
||||
bool AttribDefined;
|
||||
|
||||
CFileItem():
|
||||
HasStream(true),
|
||||
IsDir(false),
|
||||
CrcDefined(false),
|
||||
AttribDefined(false)
|
||||
{}
|
||||
void SetAttrib(UInt32 attrib)
|
||||
{
|
||||
AttribDefined = true;
|
||||
Attrib = attrib;
|
||||
}
|
||||
};
|
||||
|
||||
struct CFileItem2
|
||||
{
|
||||
UInt64 CTime;
|
||||
UInt64 ATime;
|
||||
UInt64 MTime;
|
||||
UInt64 StartPos;
|
||||
bool CTimeDefined;
|
||||
bool ATimeDefined;
|
||||
bool MTimeDefined;
|
||||
bool StartPosDefined;
|
||||
bool IsAnti;
|
||||
};
|
||||
|
||||
struct CArchiveDatabase
|
||||
{
|
||||
CRecordVector<UInt64> PackSizes;
|
||||
CRecordVector<bool> PackCRCsDefined;
|
||||
CRecordVector<UInt32> PackCRCs;
|
||||
CObjectVector<CFolder> Folders;
|
||||
CRecordVector<CNum> NumUnpackStreamsVector;
|
||||
CObjectVector<CFileItem> Files;
|
||||
|
||||
CUInt64DefVector CTime;
|
||||
CUInt64DefVector ATime;
|
||||
CUInt64DefVector MTime;
|
||||
CUInt64DefVector StartPos;
|
||||
CRecordVector<bool> IsAnti;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
PackSizes.Clear();
|
||||
PackCRCsDefined.Clear();
|
||||
PackCRCs.Clear();
|
||||
Folders.Clear();
|
||||
NumUnpackStreamsVector.Clear();
|
||||
Files.Clear();
|
||||
CTime.Clear();
|
||||
ATime.Clear();
|
||||
MTime.Clear();
|
||||
StartPos.Clear();
|
||||
IsAnti.Clear();
|
||||
}
|
||||
|
||||
void ReserveDown()
|
||||
{
|
||||
PackSizes.ReserveDown();
|
||||
PackCRCsDefined.ReserveDown();
|
||||
PackCRCs.ReserveDown();
|
||||
Folders.ReserveDown();
|
||||
NumUnpackStreamsVector.ReserveDown();
|
||||
Files.ReserveDown();
|
||||
CTime.ReserveDown();
|
||||
ATime.ReserveDown();
|
||||
MTime.ReserveDown();
|
||||
StartPos.ReserveDown();
|
||||
IsAnti.ReserveDown();
|
||||
}
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return (PackSizes.IsEmpty() &&
|
||||
PackCRCsDefined.IsEmpty() &&
|
||||
PackCRCs.IsEmpty() &&
|
||||
Folders.IsEmpty() &&
|
||||
NumUnpackStreamsVector.IsEmpty() &&
|
||||
Files.IsEmpty());
|
||||
}
|
||||
|
||||
bool CheckNumFiles() const
|
||||
{
|
||||
int size = Files.Size();
|
||||
return (
|
||||
CTime.CheckSize(size) &&
|
||||
ATime.CheckSize(size) &&
|
||||
MTime.CheckSize(size) &&
|
||||
StartPos.CheckSize(size) &&
|
||||
(size == IsAnti.Size() || IsAnti.Size() == 0));
|
||||
}
|
||||
|
||||
bool IsSolid() const
|
||||
{
|
||||
for (int i = 0; i < NumUnpackStreamsVector.Size(); i++)
|
||||
if (NumUnpackStreamsVector[i] > 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool IsItemAnti(int index) const { return (index < IsAnti.Size() && IsAnti[index]); }
|
||||
void SetItemAnti(int index, bool isAnti)
|
||||
{
|
||||
while (index >= IsAnti.Size())
|
||||
IsAnti.Add(false);
|
||||
IsAnti[index] = isAnti;
|
||||
}
|
||||
|
||||
void GetFile(int index, CFileItem &file, CFileItem2 &file2) const;
|
||||
void AddFile(const CFileItem &file, const CFileItem2 &file2);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
|
@ -1,163 +0,0 @@
|
|||
// 7zProperties.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zProperties.h"
|
||||
#include "7zHeader.h"
|
||||
#include "7zHandler.h"
|
||||
|
||||
// #define _MULTI_PACK
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
struct CPropMap
|
||||
{
|
||||
UInt64 FilePropID;
|
||||
STATPROPSTG StatPROPSTG;
|
||||
};
|
||||
|
||||
CPropMap kPropMap[] =
|
||||
{
|
||||
{ NID::kName, NULL, kpidPath, VT_BSTR},
|
||||
{ NID::kSize, NULL, kpidSize, VT_UI8},
|
||||
{ NID::kPackInfo, NULL, kpidPackSize, VT_UI8},
|
||||
|
||||
#ifdef _MULTI_PACK
|
||||
{ 100, L"Pack0", kpidPackedSize0, VT_UI8},
|
||||
{ 101, L"Pack1", kpidPackedSize1, VT_UI8},
|
||||
{ 102, L"Pack2", kpidPackedSize2, VT_UI8},
|
||||
{ 103, L"Pack3", kpidPackedSize3, VT_UI8},
|
||||
{ 104, L"Pack4", kpidPackedSize4, VT_UI8},
|
||||
#endif
|
||||
|
||||
{ NID::kCTime, NULL, kpidCTime, VT_FILETIME},
|
||||
{ NID::kMTime, NULL, kpidMTime, VT_FILETIME},
|
||||
{ NID::kATime, NULL, kpidATime, VT_FILETIME},
|
||||
{ NID::kWinAttributes, NULL, kpidAttrib, VT_UI4},
|
||||
{ NID::kStartPos, NULL, kpidPosition, VT_UI4},
|
||||
|
||||
{ NID::kCRC, NULL, kpidCRC, VT_UI4},
|
||||
|
||||
{ NID::kAnti, NULL, kpidIsAnti, VT_BOOL},
|
||||
|
||||
#ifndef _SFX
|
||||
{ 97, NULL, kpidEncrypted, VT_BOOL},
|
||||
{ 98, NULL, kpidMethod, VT_BSTR},
|
||||
{ 99, NULL, kpidBlock, VT_UI4}
|
||||
#endif
|
||||
};
|
||||
|
||||
static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);
|
||||
|
||||
static int FindPropInMap(UInt64 filePropID)
|
||||
{
|
||||
for (int i = 0; i < kPropMapSize; i++)
|
||||
if (kPropMap[i].FilePropID == filePropID)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void CopyOneItem(CRecordVector<UInt64> &src,
|
||||
CRecordVector<UInt64> &dest, UInt32 item)
|
||||
{
|
||||
for (int i = 0; i < src.Size(); i++)
|
||||
if (src[i] == item)
|
||||
{
|
||||
dest.Add(item);
|
||||
src.Delete(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void RemoveOneItem(CRecordVector<UInt64> &src, UInt32 item)
|
||||
{
|
||||
for (int i = 0; i < src.Size(); i++)
|
||||
if (src[i] == item)
|
||||
{
|
||||
src.Delete(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void InsertToHead(CRecordVector<UInt64> &dest, UInt32 item)
|
||||
{
|
||||
for (int i = 0; i < dest.Size(); i++)
|
||||
if (dest[i] == item)
|
||||
{
|
||||
dest.Delete(i);
|
||||
break;
|
||||
}
|
||||
dest.Insert(0, item);
|
||||
}
|
||||
|
||||
void CHandler::FillPopIDs()
|
||||
{
|
||||
_fileInfoPopIDs.Clear();
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
if(_volumes.Size() < 1)
|
||||
return;
|
||||
const CVolume &volume = _volumes.Front();
|
||||
const CArchiveDatabaseEx &_db = volume.Database;
|
||||
#endif
|
||||
|
||||
CRecordVector<UInt64> fileInfoPopIDs = _db.ArchiveInfo.FileInfoPopIDs;
|
||||
|
||||
RemoveOneItem(fileInfoPopIDs, NID::kEmptyStream);
|
||||
RemoveOneItem(fileInfoPopIDs, NID::kEmptyFile);
|
||||
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kName);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kAnti);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kSize);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kPackInfo);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCTime);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kMTime);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kATime);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
|
||||
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
|
||||
_fileInfoPopIDs += fileInfoPopIDs;
|
||||
|
||||
#ifndef _SFX
|
||||
_fileInfoPopIDs.Add(97);
|
||||
_fileInfoPopIDs.Add(98);
|
||||
_fileInfoPopIDs.Add(99);
|
||||
#endif
|
||||
#ifdef _MULTI_PACK
|
||||
_fileInfoPopIDs.Add(100);
|
||||
_fileInfoPopIDs.Add(101);
|
||||
_fileInfoPopIDs.Add(102);
|
||||
_fileInfoPopIDs.Add(103);
|
||||
_fileInfoPopIDs.Add(104);
|
||||
#endif
|
||||
|
||||
#ifndef _SFX
|
||||
InsertToHead(_fileInfoPopIDs, NID::kMTime);
|
||||
InsertToHead(_fileInfoPopIDs, NID::kPackInfo);
|
||||
InsertToHead(_fileInfoPopIDs, NID::kSize);
|
||||
InsertToHead(_fileInfoPopIDs, NID::kName);
|
||||
#endif
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = _fileInfoPopIDs.Size();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||
{
|
||||
if ((int)index >= _fileInfoPopIDs.Size())
|
||||
return E_INVALIDARG;
|
||||
int indexInMap = FindPropInMap(_fileInfoPopIDs[index]);
|
||||
if (indexInMap == -1)
|
||||
return E_INVALIDARG;
|
||||
const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG;
|
||||
*propID = srcItem.propid;
|
||||
*varType = srcItem.vt;
|
||||
*name = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
|
@ -1,22 +0,0 @@
|
|||
// 7zProperties.h
|
||||
|
||||
#ifndef __7Z_PROPERTIES_H
|
||||
#define __7Z_PROPERTIES_H
|
||||
|
||||
#include "../../PropID.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
enum
|
||||
{
|
||||
kpidPackedSize0 = kpidUserDefined,
|
||||
kpidPackedSize1,
|
||||
kpidPackedSize2,
|
||||
kpidPackedSize3,
|
||||
kpidPackedSize4
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
|
@ -1,18 +0,0 @@
|
|||
// 7zRegister.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../Common/RegisterArc.h"
|
||||
|
||||
#include "7zHandler.h"
|
||||
static IInArchive *CreateArc() { return new NArchive::N7z::CHandler; }
|
||||
#ifndef EXTRACT_ONLY
|
||||
static IOutArchive *CreateArcOut() { return new NArchive::N7z::CHandler; }
|
||||
#else
|
||||
#define CreateArcOut 0
|
||||
#endif
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"7z", L"7z", 0, 7, {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}, 6, false, CreateArc, CreateArcOut };
|
||||
|
||||
REGISTER_ARC(7z)
|
|
@ -1,24 +0,0 @@
|
|||
// 7zSpecStream.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "7zSpecStream.h"
|
||||
|
||||
STDMETHODIMP CSequentialInStreamSizeCount2::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 realProcessedSize;
|
||||
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
||||
_size += realProcessedSize;
|
||||
if (processedSize != 0)
|
||||
*processedSize = realProcessedSize;
|
||||
return result;
|
||||
}
|
||||
|
||||
STDMETHODIMP CSequentialInStreamSizeCount2::GetSubStreamSize(
|
||||
UInt64 subStream, UInt64 *value)
|
||||
{
|
||||
if (_getSubStreamSize == NULL)
|
||||
return E_NOTIMPL;
|
||||
return _getSubStreamSize->GetSubStreamSize(subStream, value);
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
// 7zSpecStream.h
|
||||
|
||||
#ifndef __7Z_SPEC_STREAM_H
|
||||
#define __7Z_SPEC_STREAM_H
|
||||
|
||||
#include "../../IStream.h"
|
||||
#include "../../ICoder.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
class CSequentialInStreamSizeCount2:
|
||||
public ISequentialInStream,
|
||||
public ICompressGetSubStreamSize,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CMyComPtr<ISequentialInStream> _stream;
|
||||
CMyComPtr<ICompressGetSubStreamSize> _getSubStreamSize;
|
||||
UInt64 _size;
|
||||
public:
|
||||
void Init(ISequentialInStream *stream)
|
||||
{
|
||||
_stream = stream;
|
||||
_getSubStreamSize = 0;
|
||||
_stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize);
|
||||
_size = 0;
|
||||
}
|
||||
UInt64 GetSize() const { return _size; }
|
||||
|
||||
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
|
||||
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
|
||||
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,9 +0,0 @@
|
|||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
#include "../../../Common/NewHandler.h"
|
||||
|
||||
#endif
|
|
@ -1,130 +0,0 @@
|
|||
// ArchiveExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../Common/ComTry.h"
|
||||
#include "../../Common/Types.h"
|
||||
#include "../../Windows/PropVariant.h"
|
||||
#include "../Common/RegisterArc.h"
|
||||
|
||||
#include "IArchive.h"
|
||||
#include "../ICoder.h"
|
||||
#include "../IPassword.h"
|
||||
|
||||
static const unsigned int kNumArcsMax = 32;
|
||||
static unsigned int g_NumArcs = 0;
|
||||
static const CArcInfo *g_Arcs[kNumArcsMax];
|
||||
void RegisterArc(const CArcInfo *arcInfo)
|
||||
{
|
||||
if (g_NumArcs < kNumArcsMax)
|
||||
g_Arcs[g_NumArcs++] = arcInfo;
|
||||
}
|
||||
|
||||
DEFINE_GUID(CLSID_CArchiveHandler,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
|
||||
|
||||
#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5])
|
||||
|
||||
static inline HRESULT SetPropString(const char *s, unsigned int size, PROPVARIANT *value)
|
||||
{
|
||||
if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)
|
||||
value->vt = VT_BSTR;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
|
||||
{
|
||||
return SetPropString((const char *)&guid, sizeof(GUID), value);
|
||||
}
|
||||
|
||||
int FindFormatCalssId(const GUID *clsID)
|
||||
{
|
||||
GUID cls = *clsID;
|
||||
CLS_ARC_ID_ITEM(cls) = 0;
|
||||
if (cls != CLSID_CArchiveHandler)
|
||||
return -1;
|
||||
Byte id = CLS_ARC_ID_ITEM(*clsID);
|
||||
for (unsigned i = 0; i < g_NumArcs; i++)
|
||||
if (g_Arcs[i]->ClassId == id)
|
||||
return (int)i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
{
|
||||
int needIn = (*iid == IID_IInArchive);
|
||||
int needOut = (*iid == IID_IOutArchive);
|
||||
if (!needIn && !needOut)
|
||||
return E_NOINTERFACE;
|
||||
int formatIndex = FindFormatCalssId(clsid);
|
||||
if (formatIndex < 0)
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
|
||||
const CArcInfo &arc = *g_Arcs[formatIndex];
|
||||
if (needIn)
|
||||
{
|
||||
*outObject = arc.CreateInArchive();
|
||||
((IInArchive *)*outObject)->AddRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!arc.CreateOutArchive)
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
*outObject = arc.CreateOutArchive();
|
||||
((IOutArchive *)*outObject)->AddRef();
|
||||
}
|
||||
}
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
if (formatIndex >= g_NumArcs)
|
||||
return E_INVALIDARG;
|
||||
const CArcInfo &arc = *g_Arcs[formatIndex];
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case NArchive::kName:
|
||||
prop = arc.Name;
|
||||
break;
|
||||
case NArchive::kClassID:
|
||||
{
|
||||
GUID clsId = CLSID_CArchiveHandler;
|
||||
CLS_ARC_ID_ITEM(clsId) = arc.ClassId;
|
||||
return SetPropGUID(clsId, value);
|
||||
}
|
||||
case NArchive::kExtension:
|
||||
if (arc.Ext != 0)
|
||||
prop = arc.Ext;
|
||||
break;
|
||||
case NArchive::kAddExtension:
|
||||
if (arc.AddExt != 0)
|
||||
prop = arc.AddExt;
|
||||
break;
|
||||
case NArchive::kUpdate:
|
||||
prop = (bool)(arc.CreateOutArchive != 0);
|
||||
break;
|
||||
case NArchive::kKeepName:
|
||||
prop = arc.KeepName;
|
||||
break;
|
||||
case NArchive::kStartSignature:
|
||||
return SetPropString((const char *)arc.Signature, arc.SignatureSize, value);
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
return GetHandlerProperty2(0, propID, value);
|
||||
}
|
||||
|
||||
STDAPI GetNumberOfFormats(UINT32 *numFormats)
|
||||
{
|
||||
*numFormats = g_NumArcs;
|
||||
return S_OK;
|
||||
}
|
|
@ -1,216 +0,0 @@
|
|||
// BZip2Handler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/ComTry.h"
|
||||
|
||||
#include "Windows/PropVariant.h"
|
||||
|
||||
#include "../../Common/CreateCoder.h"
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
#include "../Common/DummyOutStream.h"
|
||||
|
||||
#include "BZip2Handler.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
namespace NArchive {
|
||||
namespace NBZip2 {
|
||||
|
||||
static const CMethodId kMethodId_BZip2 = 0x040202;
|
||||
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPackSize, VT_UI8}
|
||||
};
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
*numItems = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPackSize: prop = _item.PackSize; break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream,
|
||||
const UInt64 * /* maxCheckStartPosition */,
|
||||
IArchiveOpenCallback * /* openArchiveCallback */)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
try
|
||||
{
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_streamStartPosition));
|
||||
const int kSignatureSize = 3;
|
||||
Byte buffer[kSignatureSize];
|
||||
RINOK(ReadStream_FALSE(stream, buffer, kSignatureSize));
|
||||
if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h')
|
||||
return S_FALSE;
|
||||
|
||||
UInt64 endPosition;
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_END, &endPosition));
|
||||
_item.PackSize = endPosition - _streamStartPosition;
|
||||
|
||||
_stream = stream;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
_stream.Release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
if (!allFilesMode)
|
||||
{
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
if (numItems != 1)
|
||||
return E_INVALIDARG;
|
||||
if (indices[0] != 0)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
bool testMode = (testModeSpec != 0);
|
||||
|
||||
extractCallback->SetTotal(_item.PackSize);
|
||||
|
||||
UInt64 currentTotalPacked = 0;
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalPacked));
|
||||
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
|
||||
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
||||
|
||||
if(!testMode && !realOutStream)
|
||||
return S_OK;
|
||||
|
||||
|
||||
extractCallback->PrepareOperation(askMode);
|
||||
|
||||
CMyComPtr<ICompressCoder> decoder;
|
||||
HRESULT loadResult = CreateCoder(
|
||||
EXTERNAL_CODECS_VARS
|
||||
kMethodId_BZip2, decoder, false);
|
||||
if (loadResult != S_OK || !decoder)
|
||||
{
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnSupportedMethod));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
{
|
||||
CMyComPtr<ICompressSetCoderMt> setCoderMt;
|
||||
decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
|
||||
if (setCoderMt)
|
||||
{
|
||||
RINOK(setCoderMt->SetNumberOfThreads(_numThreads));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CDummyOutStream *outStreamSpec = new CDummyOutStream;
|
||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||
outStreamSpec->SetStream(realOutStream);
|
||||
outStreamSpec->Init();
|
||||
|
||||
realOutStream.Release();
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, true);
|
||||
|
||||
RINOK(_stream->Seek(_streamStartPosition, STREAM_SEEK_SET, NULL));
|
||||
|
||||
HRESULT result = S_OK;
|
||||
|
||||
bool firstItem = true;
|
||||
for (;;)
|
||||
{
|
||||
lps->InSize = currentTotalPacked;
|
||||
lps->OutSize = outStreamSpec->GetSize();
|
||||
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
const int kSignatureSize = 3;
|
||||
Byte buffer[kSignatureSize];
|
||||
size_t processedSize = kSignatureSize;
|
||||
RINOK(ReadStream(_stream, buffer, &processedSize));
|
||||
if (processedSize != kSignatureSize)
|
||||
{
|
||||
if (firstItem)
|
||||
return E_FAIL;
|
||||
break;
|
||||
}
|
||||
if (buffer[0] != 'B' || buffer[1] != 'Z' || buffer[2] != 'h')
|
||||
{
|
||||
if (firstItem)
|
||||
return E_FAIL;
|
||||
break;
|
||||
}
|
||||
firstItem = false;
|
||||
|
||||
UInt64 dataStartPos;
|
||||
RINOK(_stream->Seek((UInt64)(Int64)(-3), STREAM_SEEK_CUR, &dataStartPos));
|
||||
|
||||
result = decoder->Code(_stream, outStream, NULL, NULL, progress);
|
||||
|
||||
if (result != S_OK)
|
||||
break;
|
||||
|
||||
CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
|
||||
decoder.QueryInterface(IID_ICompressGetInStreamProcessedSize, &getInStreamProcessedSize);
|
||||
if (!getInStreamProcessedSize)
|
||||
break;
|
||||
UInt64 packSize;
|
||||
RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize));
|
||||
UInt64 pos;
|
||||
RINOK(_stream->Seek(dataStartPos + packSize, STREAM_SEEK_SET, &pos));
|
||||
currentTotalPacked = pos - _streamStartPosition;
|
||||
}
|
||||
outStream.Release();
|
||||
|
||||
Int32 retResult;
|
||||
if (result == S_OK)
|
||||
retResult = NExtract::NOperationResult::kOK;
|
||||
else if (result == S_FALSE)
|
||||
retResult = NExtract::NOperationResult::kDataError;
|
||||
else
|
||||
return result;
|
||||
return extractCallback->SetOperationResult(retResult);
|
||||
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
IMPL_ISetCompressCodecsInfo
|
||||
|
||||
}}
|
|
@ -1,70 +0,0 @@
|
|||
// BZip2/Handler.h
|
||||
|
||||
#ifndef __BZIP2_HANDLER_H
|
||||
#define __BZIP2_HANDLER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
#include "../IArchive.h"
|
||||
#include "../../Common/CreateCoder.h"
|
||||
#include "BZip2Item.h"
|
||||
|
||||
#ifdef COMPRESS_MT
|
||||
#include "../../../Windows/System.h"
|
||||
#endif
|
||||
|
||||
namespace NArchive {
|
||||
namespace NBZip2 {
|
||||
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
public IOutArchive,
|
||||
public ISetProperties,
|
||||
PUBLIC_ISetCompressCodecsInfo
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CMyComPtr<IInStream> _stream;
|
||||
NArchive::NBZip2::CItem _item;
|
||||
UInt64 _streamStartPosition;
|
||||
|
||||
UInt32 _level;
|
||||
UInt32 _dicSize;
|
||||
UInt32 _numPasses;
|
||||
#ifdef COMPRESS_MT
|
||||
UInt32 _numThreads;
|
||||
#endif
|
||||
|
||||
DECL_EXTERNAL_CODECS_VARS
|
||||
|
||||
void InitMethodProperties()
|
||||
{
|
||||
_level = 5;
|
||||
_dicSize =
|
||||
_numPasses = 0xFFFFFFFF;
|
||||
#ifdef COMPRESS_MT
|
||||
_numThreads = NWindows::NSystem::GetNumberOfProcessors();;
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
MY_QUERYINTERFACE_BEGIN2(IInArchive)
|
||||
MY_QUERYINTERFACE_ENTRY(IOutArchive)
|
||||
MY_QUERYINTERFACE_ENTRY(ISetProperties)
|
||||
QUERY_ENTRY_ISetCompressCodecsInfo
|
||||
MY_QUERYINTERFACE_END
|
||||
MY_ADDREF_RELEASE
|
||||
|
||||
INTERFACE_IInArchive(;)
|
||||
#ifndef EXTRACT_ONLY
|
||||
INTERFACE_IOutArchive(;)
|
||||
|
||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
|
||||
#endif
|
||||
|
||||
DECL_ISetCompressCodecsInfo
|
||||
|
||||
CHandler() { InitMethodProperties(); }
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
|
@ -1,20 +0,0 @@
|
|||
// Archive/BZip2Item.h
|
||||
|
||||
#ifndef __ARCHIVE_BZIP2_ITEM_H
|
||||
#define __ARCHIVE_BZIP2_ITEM_H
|
||||
|
||||
namespace NArchive {
|
||||
namespace NBZip2 {
|
||||
|
||||
struct CItem
|
||||
{
|
||||
UInt64 PackSize;
|
||||
UInt64 UnPackSize;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
|
||||
#endif
|
|
@ -1,18 +0,0 @@
|
|||
// BZip2Register.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../Common/RegisterArc.h"
|
||||
|
||||
#include "BZip2Handler.h"
|
||||
static IInArchive *CreateArc() { return new NArchive::NBZip2::CHandler; }
|
||||
#ifndef EXTRACT_ONLY
|
||||
static IOutArchive *CreateArcOut() { return new NArchive::NBZip2::CHandler; }
|
||||
#else
|
||||
#define CreateArcOut 0
|
||||
#endif
|
||||
|
||||
static CArcInfo g_ArcInfo =
|
||||
{ L"BZip2", L"bz2 bzip2 tbz2 tbz", L"* * .tar .tar", 2, { 'B', 'Z', 'h' }, 3, true, CreateArc, CreateArcOut };
|
||||
|
||||
REGISTER_ARC(BZip2)
|
|
@ -1,121 +0,0 @@
|
|||
// CoderMixer2.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "CoderMixer2.h"
|
||||
|
||||
namespace NCoderMixer {
|
||||
|
||||
CBindReverseConverter::CBindReverseConverter(const CBindInfo &srcBindInfo):
|
||||
_srcBindInfo(srcBindInfo)
|
||||
{
|
||||
srcBindInfo.GetNumStreams(NumSrcInStreams, _numSrcOutStreams);
|
||||
|
||||
UInt32 j;
|
||||
for (j = 0; j < NumSrcInStreams; j++)
|
||||
{
|
||||
_srcInToDestOutMap.Add(0);
|
||||
DestOutToSrcInMap.Add(0);
|
||||
}
|
||||
for (j = 0; j < _numSrcOutStreams; j++)
|
||||
{
|
||||
_srcOutToDestInMap.Add(0);
|
||||
_destInToSrcOutMap.Add(0);
|
||||
}
|
||||
|
||||
UInt32 destInOffset = 0;
|
||||
UInt32 destOutOffset = 0;
|
||||
UInt32 srcInOffset = NumSrcInStreams;
|
||||
UInt32 srcOutOffset = _numSrcOutStreams;
|
||||
|
||||
for (int i = srcBindInfo.Coders.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
const CCoderStreamsInfo &srcCoderInfo = srcBindInfo.Coders[i];
|
||||
|
||||
srcInOffset -= srcCoderInfo.NumInStreams;
|
||||
srcOutOffset -= srcCoderInfo.NumOutStreams;
|
||||
|
||||
UInt32 j;
|
||||
for (j = 0; j < srcCoderInfo.NumInStreams; j++, destOutOffset++)
|
||||
{
|
||||
UInt32 index = srcInOffset + j;
|
||||
_srcInToDestOutMap[index] = destOutOffset;
|
||||
DestOutToSrcInMap[destOutOffset] = index;
|
||||
}
|
||||
for (j = 0; j < srcCoderInfo.NumOutStreams; j++, destInOffset++)
|
||||
{
|
||||
UInt32 index = srcOutOffset + j;
|
||||
_srcOutToDestInMap[index] = destInOffset;
|
||||
_destInToSrcOutMap[destInOffset] = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBindReverseConverter::CreateReverseBindInfo(CBindInfo &destBindInfo)
|
||||
{
|
||||
destBindInfo.Coders.Clear();
|
||||
destBindInfo.BindPairs.Clear();
|
||||
destBindInfo.InStreams.Clear();
|
||||
destBindInfo.OutStreams.Clear();
|
||||
|
||||
int i;
|
||||
for (i = _srcBindInfo.Coders.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
const CCoderStreamsInfo &srcCoderInfo = _srcBindInfo.Coders[i];
|
||||
CCoderStreamsInfo destCoderInfo;
|
||||
destCoderInfo.NumInStreams = srcCoderInfo.NumOutStreams;
|
||||
destCoderInfo.NumOutStreams = srcCoderInfo.NumInStreams;
|
||||
destBindInfo.Coders.Add(destCoderInfo);
|
||||
}
|
||||
for (i = _srcBindInfo.BindPairs.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
const CBindPair &srcBindPair = _srcBindInfo.BindPairs[i];
|
||||
CBindPair destBindPair;
|
||||
destBindPair.InIndex = _srcOutToDestInMap[srcBindPair.OutIndex];
|
||||
destBindPair.OutIndex = _srcInToDestOutMap[srcBindPair.InIndex];
|
||||
destBindInfo.BindPairs.Add(destBindPair);
|
||||
}
|
||||
for (i = 0; i < _srcBindInfo.InStreams.Size(); i++)
|
||||
destBindInfo.OutStreams.Add(_srcInToDestOutMap[_srcBindInfo.InStreams[i]]);
|
||||
for (i = 0; i < _srcBindInfo.OutStreams.Size(); i++)
|
||||
destBindInfo.InStreams.Add(_srcOutToDestInMap[_srcBindInfo.OutStreams[i]]);
|
||||
}
|
||||
|
||||
CCoderInfo2::CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams):
|
||||
NumInStreams(numInStreams),
|
||||
NumOutStreams(numOutStreams)
|
||||
{
|
||||
InSizes.Reserve(NumInStreams);
|
||||
InSizePointers.Reserve(NumInStreams);
|
||||
OutSizePointers.Reserve(NumOutStreams);
|
||||
OutSizePointers.Reserve(NumOutStreams);
|
||||
}
|
||||
|
||||
static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
|
||||
CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
|
||||
{
|
||||
sizes.Clear();
|
||||
sizePointers.Clear();
|
||||
for(UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
if (srcSizes == 0 || srcSizes[i] == NULL)
|
||||
{
|
||||
sizes.Add(0);
|
||||
sizePointers.Add(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
sizes.Add(*srcSizes[i]);
|
||||
sizePointers.Add(&sizes.Back());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCoderInfo2::SetCoderInfo(const UInt64 **inSizes,
|
||||
const UInt64 **outSizes)
|
||||
{
|
||||
SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
|
||||
SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,174 +0,0 @@
|
|||
// CoderMixer2.h
|
||||
|
||||
#ifndef __CODER_MIXER2_H
|
||||
#define __CODER_MIXER2_H
|
||||
|
||||
#include "../../../Common/MyVector.h"
|
||||
#include "../../../Common/Types.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../ICoder.h"
|
||||
|
||||
namespace NCoderMixer {
|
||||
|
||||
struct CBindPair
|
||||
{
|
||||
UInt32 InIndex;
|
||||
UInt32 OutIndex;
|
||||
};
|
||||
|
||||
struct CCoderStreamsInfo
|
||||
{
|
||||
UInt32 NumInStreams;
|
||||
UInt32 NumOutStreams;
|
||||
};
|
||||
|
||||
struct CBindInfo
|
||||
{
|
||||
CRecordVector<CCoderStreamsInfo> Coders;
|
||||
CRecordVector<CBindPair> BindPairs;
|
||||
CRecordVector<UInt32> InStreams;
|
||||
CRecordVector<UInt32> OutStreams;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Coders.Clear();
|
||||
BindPairs.Clear();
|
||||
InStreams.Clear();
|
||||
OutStreams.Clear();
|
||||
}
|
||||
|
||||
/*
|
||||
UInt32 GetCoderStartOutStream(UInt32 coderIndex) const
|
||||
{
|
||||
UInt32 numOutStreams = 0;
|
||||
for (UInt32 i = 0; i < coderIndex; i++)
|
||||
numOutStreams += Coders[i].NumOutStreams;
|
||||
return numOutStreams;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void GetNumStreams(UInt32 &numInStreams, UInt32 &numOutStreams) const
|
||||
{
|
||||
numInStreams = 0;
|
||||
numOutStreams = 0;
|
||||
for (int i = 0; i < Coders.Size(); i++)
|
||||
{
|
||||
const CCoderStreamsInfo &coderStreamsInfo = Coders[i];
|
||||
numInStreams += coderStreamsInfo.NumInStreams;
|
||||
numOutStreams += coderStreamsInfo.NumOutStreams;
|
||||
}
|
||||
}
|
||||
|
||||
int FindBinderForInStream(UInt32 inStream) const
|
||||
{
|
||||
for (int i = 0; i < BindPairs.Size(); i++)
|
||||
if (BindPairs[i].InIndex == inStream)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
int FindBinderForOutStream(UInt32 outStream) const
|
||||
{
|
||||
for (int i = 0; i < BindPairs.Size(); i++)
|
||||
if (BindPairs[i].OutIndex == outStream)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
UInt32 GetCoderInStreamIndex(UInt32 coderIndex) const
|
||||
{
|
||||
UInt32 streamIndex = 0;
|
||||
for (UInt32 i = 0; i < coderIndex; i++)
|
||||
streamIndex += Coders[i].NumInStreams;
|
||||
return streamIndex;
|
||||
}
|
||||
|
||||
UInt32 GetCoderOutStreamIndex(UInt32 coderIndex) const
|
||||
{
|
||||
UInt32 streamIndex = 0;
|
||||
for (UInt32 i = 0; i < coderIndex; i++)
|
||||
streamIndex += Coders[i].NumOutStreams;
|
||||
return streamIndex;
|
||||
}
|
||||
|
||||
|
||||
void FindInStream(UInt32 streamIndex, UInt32 &coderIndex,
|
||||
UInt32 &coderStreamIndex) const
|
||||
{
|
||||
for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
|
||||
{
|
||||
UInt32 curSize = Coders[coderIndex].NumInStreams;
|
||||
if (streamIndex < curSize)
|
||||
{
|
||||
coderStreamIndex = streamIndex;
|
||||
return;
|
||||
}
|
||||
streamIndex -= curSize;
|
||||
}
|
||||
throw 1;
|
||||
}
|
||||
void FindOutStream(UInt32 streamIndex, UInt32 &coderIndex,
|
||||
UInt32 &coderStreamIndex) const
|
||||
{
|
||||
for (coderIndex = 0; coderIndex < (UInt32)Coders.Size(); coderIndex++)
|
||||
{
|
||||
UInt32 curSize = Coders[coderIndex].NumOutStreams;
|
||||
if (streamIndex < curSize)
|
||||
{
|
||||
coderStreamIndex = streamIndex;
|
||||
return;
|
||||
}
|
||||
streamIndex -= curSize;
|
||||
}
|
||||
throw 1;
|
||||
}
|
||||
};
|
||||
|
||||
class CBindReverseConverter
|
||||
{
|
||||
UInt32 _numSrcOutStreams;
|
||||
NCoderMixer::CBindInfo _srcBindInfo;
|
||||
CRecordVector<UInt32> _srcInToDestOutMap;
|
||||
CRecordVector<UInt32> _srcOutToDestInMap;
|
||||
CRecordVector<UInt32> _destInToSrcOutMap;
|
||||
public:
|
||||
UInt32 NumSrcInStreams;
|
||||
CRecordVector<UInt32> DestOutToSrcInMap;
|
||||
|
||||
CBindReverseConverter(const NCoderMixer::CBindInfo &srcBindInfo);
|
||||
void CreateReverseBindInfo(NCoderMixer::CBindInfo &destBindInfo);
|
||||
};
|
||||
|
||||
struct CCoderInfo2
|
||||
{
|
||||
CMyComPtr<ICompressCoder> Coder;
|
||||
CMyComPtr<ICompressCoder2> Coder2;
|
||||
UInt32 NumInStreams;
|
||||
UInt32 NumOutStreams;
|
||||
|
||||
CRecordVector<UInt64> InSizes;
|
||||
CRecordVector<UInt64> OutSizes;
|
||||
CRecordVector<const UInt64 *> InSizePointers;
|
||||
CRecordVector<const UInt64 *> OutSizePointers;
|
||||
|
||||
CCoderInfo2(UInt32 numInStreams, UInt32 numOutStreams);
|
||||
void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
|
||||
|
||||
HRESULT QueryInterface(REFGUID iid, void** pp) const
|
||||
{
|
||||
IUnknown *p = Coder ? (IUnknown *)Coder : (IUnknown *)Coder2;
|
||||
return p->QueryInterface(iid, pp);
|
||||
}
|
||||
};
|
||||
|
||||
class CCoderMixer2
|
||||
{
|
||||
public:
|
||||
virtual HRESULT SetBindInfo(const CBindInfo &bindInfo) = 0;
|
||||
virtual void ReInit() = 0;
|
||||
virtual void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,230 +0,0 @@
|
|||
// CoderMixer2MT.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "CoderMixer2MT.h"
|
||||
|
||||
namespace NCoderMixer {
|
||||
|
||||
CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams):
|
||||
CCoderInfo2(numInStreams, numOutStreams)
|
||||
{
|
||||
InStreams.Reserve(NumInStreams);
|
||||
InStreamPointers.Reserve(NumInStreams);
|
||||
OutStreams.Reserve(NumOutStreams);
|
||||
OutStreamPointers.Reserve(NumOutStreams);
|
||||
}
|
||||
|
||||
void CCoder2::Execute() { Code(NULL); }
|
||||
|
||||
void CCoder2::Code(ICompressProgressInfo *progress)
|
||||
{
|
||||
InStreamPointers.Clear();
|
||||
OutStreamPointers.Clear();
|
||||
UInt32 i;
|
||||
for (i = 0; i < NumInStreams; i++)
|
||||
{
|
||||
if (InSizePointers[i] != NULL)
|
||||
InSizePointers[i] = &InSizes[i];
|
||||
InStreamPointers.Add((ISequentialInStream *)InStreams[i]);
|
||||
}
|
||||
for (i = 0; i < NumOutStreams; i++)
|
||||
{
|
||||
if (OutSizePointers[i] != NULL)
|
||||
OutSizePointers[i] = &OutSizes[i];
|
||||
OutStreamPointers.Add((ISequentialOutStream *)OutStreams[i]);
|
||||
}
|
||||
if (Coder)
|
||||
Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0],
|
||||
InSizePointers[0], OutSizePointers[0], progress);
|
||||
else
|
||||
Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams,
|
||||
&OutStreamPointers.Front(), &OutSizePointers.Front(), NumOutStreams, progress);
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < InStreams.Size(); i++)
|
||||
InStreams[i].Release();
|
||||
for (i = 0; i < OutStreams.Size(); i++)
|
||||
OutStreams[i].Release();
|
||||
}
|
||||
}
|
||||
|
||||
static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
|
||||
CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
|
||||
{
|
||||
sizes.Clear();
|
||||
sizePointers.Clear();
|
||||
for(UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
if (srcSizes == 0 || srcSizes[i] == NULL)
|
||||
{
|
||||
sizes.Add(0);
|
||||
sizePointers.Add(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
sizes.Add(*srcSizes[i]);
|
||||
sizePointers.Add(&sizes.Back());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes)
|
||||
{
|
||||
SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
|
||||
SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// CCoderMixer2MT
|
||||
|
||||
HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)
|
||||
{
|
||||
_bindInfo = bindInfo;
|
||||
_streamBinders.Clear();
|
||||
for(int i = 0; i < _bindInfo.BindPairs.Size(); i++)
|
||||
{
|
||||
_streamBinders.Add(CStreamBinder());
|
||||
RINOK(_streamBinders.Back().CreateEvents());
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CCoderMixer2MT::AddCoderCommon()
|
||||
{
|
||||
const CCoderStreamsInfo &c = _bindInfo.Coders[_coders.Size()];
|
||||
CCoder2 threadCoderInfo(c.NumInStreams, c.NumOutStreams);
|
||||
_coders.Add(threadCoderInfo);
|
||||
}
|
||||
|
||||
void CCoderMixer2MT::AddCoder(ICompressCoder *coder)
|
||||
{
|
||||
AddCoderCommon();
|
||||
_coders.Back().Coder = coder;
|
||||
}
|
||||
|
||||
void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)
|
||||
{
|
||||
AddCoderCommon();
|
||||
_coders.Back().Coder2 = coder;
|
||||
}
|
||||
|
||||
|
||||
void CCoderMixer2MT::ReInit()
|
||||
{
|
||||
for(int i = 0; i < _streamBinders.Size(); i++)
|
||||
_streamBinders[i].ReInit();
|
||||
}
|
||||
|
||||
|
||||
HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams)
|
||||
{
|
||||
/*
|
||||
if (_coders.Size() != _bindInfo.Coders.Size())
|
||||
throw 0;
|
||||
*/
|
||||
int i;
|
||||
for(i = 0; i < _coders.Size(); i++)
|
||||
{
|
||||
CCoder2 &coderInfo = _coders[i];
|
||||
const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i];
|
||||
coderInfo.InStreams.Clear();
|
||||
UInt32 j;
|
||||
for(j = 0; j < coderStreamsInfo.NumInStreams; j++)
|
||||
coderInfo.InStreams.Add(NULL);
|
||||
coderInfo.OutStreams.Clear();
|
||||
for(j = 0; j < coderStreamsInfo.NumOutStreams; j++)
|
||||
coderInfo.OutStreams.Add(NULL);
|
||||
}
|
||||
|
||||
for(i = 0; i < _bindInfo.BindPairs.Size(); i++)
|
||||
{
|
||||
const CBindPair &bindPair = _bindInfo.BindPairs[i];
|
||||
UInt32 inCoderIndex, inCoderStreamIndex;
|
||||
UInt32 outCoderIndex, outCoderStreamIndex;
|
||||
_bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex);
|
||||
_bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex);
|
||||
|
||||
_streamBinders[i].CreateStreams(
|
||||
&_coders[inCoderIndex].InStreams[inCoderStreamIndex],
|
||||
&_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
|
||||
}
|
||||
|
||||
for(i = 0; i < _bindInfo.InStreams.Size(); i++)
|
||||
{
|
||||
UInt32 inCoderIndex, inCoderStreamIndex;
|
||||
_bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex);
|
||||
_coders[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i];
|
||||
}
|
||||
|
||||
for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
|
||||
{
|
||||
UInt32 outCoderIndex, outCoderStreamIndex;
|
||||
_bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex);
|
||||
_coders[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i];
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CCoderMixer2MT::ReturnIfError(HRESULT code)
|
||||
{
|
||||
for (int i = 0; i < _coders.Size(); i++)
|
||||
if (_coders[i].Result == code)
|
||||
return code;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
|
||||
const UInt64 ** /* inSizes */,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UInt64 ** /* outSizes */,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
|
||||
numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
|
||||
return E_INVALIDARG;
|
||||
|
||||
Init(inStreams, outStreams);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < _coders.Size(); i++)
|
||||
if (i != _progressCoderIndex)
|
||||
{
|
||||
RINOK(_coders[i].Create());
|
||||
}
|
||||
|
||||
for (i = 0; i < _coders.Size(); i++)
|
||||
if (i != _progressCoderIndex)
|
||||
_coders[i].Start();
|
||||
|
||||
_coders[_progressCoderIndex].Code(progress);
|
||||
|
||||
for (i = 0; i < _coders.Size(); i++)
|
||||
if (i != _progressCoderIndex)
|
||||
_coders[i].WaitFinish();
|
||||
|
||||
RINOK(ReturnIfError(E_ABORT));
|
||||
RINOK(ReturnIfError(E_OUTOFMEMORY));
|
||||
|
||||
for (i = 0; i < _coders.Size(); i++)
|
||||
{
|
||||
HRESULT result = _coders[i].Result;
|
||||
if (result != S_OK && result != E_FAIL && result != S_FALSE)
|
||||
return result;
|
||||
}
|
||||
|
||||
RINOK(ReturnIfError(S_FALSE));
|
||||
|
||||
for (i = 0; i < _coders.Size(); i++)
|
||||
{
|
||||
HRESULT result = _coders[i].Result;
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
// CoderMixer2MT.h
|
||||
|
||||
#ifndef __CODER_MIXER2_MT_H
|
||||
#define __CODER_MIXER2_MT_H
|
||||
|
||||
#include "CoderMixer2.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../Common/StreamBinder.h"
|
||||
#include "../../Common/VirtThread.h"
|
||||
|
||||
namespace NCoderMixer {
|
||||
|
||||
struct CCoder2: public CCoderInfo2, public CVirtThread
|
||||
{
|
||||
HRESULT Result;
|
||||
CObjectVector< CMyComPtr<ISequentialInStream> > InStreams;
|
||||
CObjectVector< CMyComPtr<ISequentialOutStream> > OutStreams;
|
||||
CRecordVector<ISequentialInStream*> InStreamPointers;
|
||||
CRecordVector<ISequentialOutStream*> OutStreamPointers;
|
||||
|
||||
CCoder2(UInt32 numInStreams, UInt32 numOutStreams);
|
||||
void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
|
||||
virtual void Execute();
|
||||
void Code(ICompressProgressInfo *progress);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
SetBindInfo()
|
||||
for each coder
|
||||
AddCoder[2]()
|
||||
SetProgressIndex(UInt32 coderIndex);
|
||||
|
||||
for each file
|
||||
{
|
||||
ReInit()
|
||||
for each coder
|
||||
SetCoderInfo
|
||||
Code
|
||||
}
|
||||
*/
|
||||
|
||||
class CCoderMixer2MT:
|
||||
public ICompressCoder2,
|
||||
public CCoderMixer2,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CBindInfo _bindInfo;
|
||||
CObjectVector<CStreamBinder> _streamBinders;
|
||||
int _progressCoderIndex;
|
||||
|
||||
void AddCoderCommon();
|
||||
HRESULT Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams);
|
||||
HRESULT ReturnIfError(HRESULT code);
|
||||
public:
|
||||
CObjectVector<CCoder2> _coders;
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Code)(ISequentialInStream **inStreams,
|
||||
const UInt64 **inSizes,
|
||||
UInt32 numInStreams,
|
||||
ISequentialOutStream **outStreams,
|
||||
const UInt64 **outSizes,
|
||||
UInt32 numOutStreams,
|
||||
ICompressProgressInfo *progress);
|
||||
|
||||
HRESULT SetBindInfo(const CBindInfo &bindInfo);
|
||||
void AddCoder(ICompressCoder *coder);
|
||||
void AddCoder2(ICompressCoder2 *coder);
|
||||
void SetProgressCoderIndex(int coderIndex) { _progressCoderIndex = coderIndex; }
|
||||
|
||||
void ReInit();
|
||||
void SetCoderInfo(UInt32 coderIndex, const UInt64 **inSizes, const UInt64 **outSizes)
|
||||
{ _coders[coderIndex].SetCoderInfo(inSizes, outSizes); }
|
||||
UInt64 GetWriteProcessedSize(UInt32 binderIndex) const
|
||||
{ return _streamBinders[binderIndex].ProcessedSize; }
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
|
@ -1,22 +0,0 @@
|
|||
// DummyOutStream.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "DummyOutStream.h"
|
||||
|
||||
STDMETHODIMP CDummyOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 realProcessedSize;
|
||||
HRESULT result;
|
||||
if(!_stream)
|
||||
{
|
||||
realProcessedSize = size;
|
||||
result = S_OK;
|
||||
}
|
||||
else
|
||||
result = _stream->Write(data, size, &realProcessedSize);
|
||||
_size += realProcessedSize;
|
||||
if(processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
return result;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
// DummyOutStream.h
|
||||
|
||||
#ifndef __DUMMYOUTSTREAM_H
|
||||
#define __DUMMYOUTSTREAM_H
|
||||
|
||||
#include "../../IStream.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
class CDummyOutStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> _stream;
|
||||
UInt64 _size;
|
||||
public:
|
||||
void SetStream(ISequentialOutStream *outStream) { _stream = outStream; }
|
||||
void ReleaseStream() { _stream.Release(); }
|
||||
void Init() { _size = 0; }
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
UInt64 GetSize() const { return _size; }
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,62 +0,0 @@
|
|||
// FindSignature.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "Common/Buffer.h"
|
||||
|
||||
#include "FindSignature.h"
|
||||
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
HRESULT FindSignatureInStream(ISequentialInStream *stream,
|
||||
const Byte *signature, unsigned signatureSize,
|
||||
const UInt64 *limit, UInt64 &resPos)
|
||||
{
|
||||
resPos = 0;
|
||||
CByteBuffer byteBuffer2;
|
||||
byteBuffer2.SetCapacity(signatureSize);
|
||||
RINOK(ReadStream_FALSE(stream, byteBuffer2, signatureSize));
|
||||
|
||||
if (memcmp(byteBuffer2, signature, signatureSize) == 0)
|
||||
return S_OK;
|
||||
|
||||
const UInt32 kBufferSize = (1 << 16);
|
||||
CByteBuffer byteBuffer;
|
||||
byteBuffer.SetCapacity(kBufferSize);
|
||||
Byte *buffer = byteBuffer;
|
||||
UInt32 numPrevBytes = signatureSize - 1;
|
||||
memcpy(buffer, (const Byte *)byteBuffer2 + 1, numPrevBytes);
|
||||
resPos = 1;
|
||||
for (;;)
|
||||
{
|
||||
if (limit != NULL)
|
||||
if (resPos > *limit)
|
||||
return S_FALSE;
|
||||
do
|
||||
{
|
||||
UInt32 numReadBytes = kBufferSize - numPrevBytes;
|
||||
UInt32 processedSize;
|
||||
RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
|
||||
numPrevBytes += processedSize;
|
||||
if (processedSize == 0)
|
||||
return S_FALSE;
|
||||
}
|
||||
while (numPrevBytes < signatureSize);
|
||||
UInt32 numTests = numPrevBytes - signatureSize + 1;
|
||||
for (UInt32 pos = 0; pos < numTests; pos++)
|
||||
{
|
||||
Byte b = signature[0];
|
||||
for (; buffer[pos] != b && pos < numTests; pos++);
|
||||
if (pos == numTests)
|
||||
break;
|
||||
if (memcmp(buffer + pos, signature, signatureSize) == 0)
|
||||
{
|
||||
resPos += pos;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
resPos += numTests;
|
||||
numPrevBytes -= numTests;
|
||||
memmove(buffer, buffer + numTests, numPrevBytes);
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
// FindSignature.h
|
||||
|
||||
#ifndef __FINDSIGNATURE_H
|
||||
#define __FINDSIGNATURE_H
|
||||
|
||||
#include "../../IStream.h"
|
||||
|
||||
HRESULT FindSignatureInStream(ISequentialInStream *stream,
|
||||
const Byte *signature, unsigned signatureSize,
|
||||
const UInt64 *limit, UInt64 &resPos);
|
||||
|
||||
#endif
|
|
@ -1,40 +0,0 @@
|
|||
// InStreamWithCRC.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "InStreamWithCRC.h"
|
||||
|
||||
STDMETHODIMP CSequentialInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 realProcessedSize;
|
||||
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
||||
_size += realProcessedSize;
|
||||
if (size > 0 && realProcessedSize == 0)
|
||||
_wasFinished = true;
|
||||
_crc = CrcUpdate(_crc, data, realProcessedSize);
|
||||
if(processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
return result;
|
||||
}
|
||||
|
||||
STDMETHODIMP CInStreamWithCRC::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 realProcessedSize;
|
||||
HRESULT result = _stream->Read(data, size, &realProcessedSize);
|
||||
if (size > 0 && realProcessedSize == 0)
|
||||
_wasFinished = true;
|
||||
_size += realProcessedSize;
|
||||
_crc = CrcUpdate(_crc, data, realProcessedSize);
|
||||
if(processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
return result;
|
||||
}
|
||||
|
||||
STDMETHODIMP CInStreamWithCRC::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
|
||||
{
|
||||
if (seekOrigin != STREAM_SEEK_SET || offset != 0)
|
||||
return E_FAIL;
|
||||
_size = 0;
|
||||
_crc = CRC_INIT_VAL;
|
||||
return _stream->Seek(offset, seekOrigin, newPosition);
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
// InStreamWithCRC.h
|
||||
|
||||
#ifndef __INSTREAMWITHCRC_H
|
||||
#define __INSTREAMWITHCRC_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../IStream.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/7zCrc.h"
|
||||
}
|
||||
|
||||
class CSequentialInStreamWithCRC:
|
||||
public ISequentialInStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
private:
|
||||
CMyComPtr<ISequentialInStream> _stream;
|
||||
UInt64 _size;
|
||||
UInt32 _crc;
|
||||
bool _wasFinished;
|
||||
public:
|
||||
void SetStream(ISequentialInStream *stream) { _stream = stream; }
|
||||
void Init()
|
||||
{
|
||||
_size = 0;
|
||||
_wasFinished = false;
|
||||
_crc = CRC_INIT_VAL;
|
||||
}
|
||||
void ReleaseStream() { _stream.Release(); }
|
||||
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
|
||||
UInt64 GetSize() const { return _size; }
|
||||
bool WasFinished() const { return _wasFinished; }
|
||||
};
|
||||
|
||||
class CInStreamWithCRC:
|
||||
public IInStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(IInStream)
|
||||
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
|
||||
private:
|
||||
CMyComPtr<IInStream> _stream;
|
||||
UInt64 _size;
|
||||
UInt32 _crc;
|
||||
bool _wasFinished;
|
||||
public:
|
||||
void SetStream(IInStream *stream) { _stream = stream; }
|
||||
void Init()
|
||||
{
|
||||
_size = 0;
|
||||
_wasFinished = false;
|
||||
_crc = CRC_INIT_VAL;
|
||||
}
|
||||
void ReleaseStream() { _stream.Release(); }
|
||||
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
|
||||
UInt64 GetSize() const { return _size; }
|
||||
bool WasFinished() const { return _wasFinished; }
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,59 +0,0 @@
|
|||
// Archive/Common/ItemNameUtils.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ItemNameUtils.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NItemName {
|
||||
|
||||
static const wchar_t kOSDirDelimiter = WCHAR_PATH_SEPARATOR;
|
||||
static const wchar_t kDirDelimiter = L'/';
|
||||
|
||||
UString MakeLegalName(const UString &name)
|
||||
{
|
||||
UString zipName = name;
|
||||
zipName.Replace(kOSDirDelimiter, kDirDelimiter);
|
||||
return zipName;
|
||||
}
|
||||
|
||||
UString GetOSName(const UString &name)
|
||||
{
|
||||
UString newName = name;
|
||||
newName.Replace(kDirDelimiter, kOSDirDelimiter);
|
||||
return newName;
|
||||
}
|
||||
|
||||
UString GetOSName2(const UString &name)
|
||||
{
|
||||
if (name.IsEmpty())
|
||||
return UString();
|
||||
UString newName = GetOSName(name);
|
||||
if (newName[newName.Length() - 1] == kOSDirDelimiter)
|
||||
newName.Delete(newName.Length() - 1);
|
||||
return newName;
|
||||
}
|
||||
|
||||
bool HasTailSlash(const AString &name, UINT codePage)
|
||||
{
|
||||
if (name.IsEmpty())
|
||||
return false;
|
||||
LPCSTR prev =
|
||||
#ifdef _WIN32
|
||||
CharPrevExA((WORD)codePage, name, &name[name.Length()], 0);
|
||||
#else
|
||||
(LPCSTR)(name) + (name.Length() - 1);
|
||||
#endif
|
||||
return (*prev == '/');
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
UString WinNameToOSName(const UString &name)
|
||||
{
|
||||
UString newName = name;
|
||||
newName.Replace(L'\\', kOSDirDelimiter);
|
||||
return newName;
|
||||
}
|
||||
#endif
|
||||
|
||||
}}
|
|
@ -1,24 +0,0 @@
|
|||
// Archive/Common/ItemNameUtils.h
|
||||
|
||||
#ifndef __ARCHIVE_ITEMNAMEUTILS_H
|
||||
#define __ARCHIVE_ITEMNAMEUTILS_H
|
||||
|
||||
#include "../../../Common/MyString.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NItemName {
|
||||
|
||||
UString MakeLegalName(const UString &name);
|
||||
UString GetOSName(const UString &name);
|
||||
UString GetOSName2(const UString &name);
|
||||
bool HasTailSlash(const AString &name, UINT codePage);
|
||||
|
||||
#ifdef _WIN32
|
||||
inline UString WinNameToOSName(const UString &name) { return name; }
|
||||
#else
|
||||
UString WinNameToOSName(const UString &name);
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
|
@ -1,201 +0,0 @@
|
|||
// MultiStream.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "MultiStream.h"
|
||||
|
||||
STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
if(processedSize != NULL)
|
||||
*processedSize = 0;
|
||||
while(_streamIndex < Streams.Size() && size > 0)
|
||||
{
|
||||
CSubStreamInfo &s = Streams[_streamIndex];
|
||||
if (_pos == s.Size)
|
||||
{
|
||||
_streamIndex++;
|
||||
_pos = 0;
|
||||
continue;
|
||||
}
|
||||
RINOK(s.Stream->Seek(s.Pos + _pos, STREAM_SEEK_SET, 0));
|
||||
UInt32 sizeToRead = UInt32(MyMin((UInt64)size, s.Size - _pos));
|
||||
UInt32 realProcessed;
|
||||
HRESULT result = s.Stream->Read(data, sizeToRead, &realProcessed);
|
||||
data = (void *)((Byte *)data + realProcessed);
|
||||
size -= realProcessed;
|
||||
if(processedSize != NULL)
|
||||
*processedSize += realProcessed;
|
||||
_pos += realProcessed;
|
||||
_seekPos += realProcessed;
|
||||
RINOK(result);
|
||||
break;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin,
|
||||
UInt64 *newPosition)
|
||||
{
|
||||
UInt64 newPos;
|
||||
switch(seekOrigin)
|
||||
{
|
||||
case STREAM_SEEK_SET:
|
||||
newPos = offset;
|
||||
break;
|
||||
case STREAM_SEEK_CUR:
|
||||
newPos = _seekPos + offset;
|
||||
break;
|
||||
case STREAM_SEEK_END:
|
||||
newPos = _totalLength + offset;
|
||||
break;
|
||||
default:
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
}
|
||||
_seekPos = 0;
|
||||
for (_streamIndex = 0; _streamIndex < Streams.Size(); _streamIndex++)
|
||||
{
|
||||
UInt64 size = Streams[_streamIndex].Size;
|
||||
if (newPos < _seekPos + size)
|
||||
{
|
||||
_pos = newPos - _seekPos;
|
||||
_seekPos += _pos;
|
||||
if (newPosition != 0)
|
||||
*newPosition = newPos;
|
||||
return S_OK;
|
||||
}
|
||||
_seekPos += size;
|
||||
}
|
||||
if (newPos == _seekPos)
|
||||
{
|
||||
if (newPosition != 0)
|
||||
*newPosition = newPos;
|
||||
return S_OK;
|
||||
}
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
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 COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
if(processedSize != NULL)
|
||||
*processedSize = 0;
|
||||
while(size > 0)
|
||||
{
|
||||
if (_streamIndex >= Streams.Size())
|
||||
{
|
||||
CSubStreamInfo subStream;
|
||||
RINOK(VolumeCallback->GetVolumeSize(Streams.Size(), &subStream.Size));
|
||||
RINOK(VolumeCallback->GetVolumeStream(Streams.Size(), &subStream.Stream));
|
||||
subStream.Pos = 0;
|
||||
Streams.Add(subStream);
|
||||
continue;
|
||||
}
|
||||
CSubStreamInfo &subStream = Streams[_streamIndex];
|
||||
if (_offsetPos >= subStream.Size)
|
||||
{
|
||||
_offsetPos -= subStream.Size;
|
||||
_streamIndex++;
|
||||
continue;
|
||||
}
|
||||
if (_offsetPos != subStream.Pos)
|
||||
{
|
||||
CMyComPtr<IOutStream> outStream;
|
||||
RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream));
|
||||
RINOK(outStream->Seek(_offsetPos, STREAM_SEEK_SET, NULL));
|
||||
subStream.Pos = _offsetPos;
|
||||
}
|
||||
|
||||
UInt32 curSize = (UInt32)MyMin((UInt64)size, subStream.Size - subStream.Pos);
|
||||
UInt32 realProcessed;
|
||||
RINOK(subStream.Stream->Write(data, curSize, &realProcessed));
|
||||
data = (void *)((Byte *)data + realProcessed);
|
||||
size -= realProcessed;
|
||||
subStream.Pos += realProcessed;
|
||||
_offsetPos += realProcessed;
|
||||
_absPos += realProcessed;
|
||||
if (_absPos > _length)
|
||||
_length = _absPos;
|
||||
if(processedSize != NULL)
|
||||
*processedSize += realProcessed;
|
||||
if (subStream.Pos == subStream.Size)
|
||||
{
|
||||
_streamIndex++;
|
||||
_offsetPos = 0;
|
||||
}
|
||||
if (realProcessed != curSize && realProcessed == 0)
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP COutMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
|
||||
{
|
||||
if(seekOrigin >= 3)
|
||||
return STG_E_INVALIDFUNCTION;
|
||||
switch(seekOrigin)
|
||||
{
|
||||
case STREAM_SEEK_SET:
|
||||
_absPos = offset;
|
||||
break;
|
||||
case STREAM_SEEK_CUR:
|
||||
_absPos += offset;
|
||||
break;
|
||||
case STREAM_SEEK_END:
|
||||
_absPos = _length + offset;
|
||||
break;
|
||||
}
|
||||
_offsetPos = _absPos;
|
||||
_streamIndex = 0;
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
|
@ -1,76 +0,0 @@
|
|||
// MultiStream.h
|
||||
|
||||
#ifndef __MULTISTREAM_H
|
||||
#define __MULTISTREAM_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../../Common/MyVector.h"
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
class CMultiStream:
|
||||
public IInStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
int _streamIndex;
|
||||
UInt64 _pos;
|
||||
UInt64 _seekPos;
|
||||
UInt64 _totalLength;
|
||||
public:
|
||||
struct CSubStreamInfo
|
||||
{
|
||||
CMyComPtr<IInStream> Stream;
|
||||
UInt64 Pos;
|
||||
UInt64 Size;
|
||||
};
|
||||
CObjectVector<CSubStreamInfo> Streams;
|
||||
void Init()
|
||||
{
|
||||
_streamIndex = 0;
|
||||
_pos = 0;
|
||||
_seekPos = 0;
|
||||
_totalLength = 0;
|
||||
for (int i = 0; i < Streams.Size(); i++)
|
||||
_totalLength += Streams[i].Size;
|
||||
}
|
||||
|
||||
MY_UNKNOWN_IMP1(IInStream)
|
||||
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
|
||||
};
|
||||
|
||||
/*
|
||||
class COutMultiStream:
|
||||
public IOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
int _streamIndex; // required stream
|
||||
UInt64 _offsetPos; // offset from start of _streamIndex index
|
||||
UInt64 _absPos;
|
||||
UInt64 _length;
|
||||
|
||||
struct CSubStreamInfo
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> Stream;
|
||||
UInt64 Size;
|
||||
UInt64 Pos;
|
||||
};
|
||||
CObjectVector<CSubStreamInfo> Streams;
|
||||
public:
|
||||
CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
|
||||
void Init()
|
||||
{
|
||||
_streamIndex = 0;
|
||||
_offsetPos = 0;
|
||||
_absPos = 0;
|
||||
_length = 0;
|
||||
}
|
||||
|
||||
MY_UNKNOWN_IMP1(IOutStream)
|
||||
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
|
||||
};
|
||||
*/
|
||||
|
||||
#endif
|
|
@ -1,24 +0,0 @@
|
|||
// OutStreamWithCRC.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "OutStreamWithCRC.h"
|
||||
|
||||
STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 realProcessedSize;
|
||||
HRESULT result;
|
||||
if(!_stream)
|
||||
{
|
||||
realProcessedSize = size;
|
||||
result = S_OK;
|
||||
}
|
||||
else
|
||||
result = _stream->Write(data, size, &realProcessedSize);
|
||||
if (_calculate)
|
||||
_crc = CrcUpdate(_crc, data, realProcessedSize);
|
||||
_size += realProcessedSize;
|
||||
if(processedSize != NULL)
|
||||
*processedSize = realProcessedSize;
|
||||
return result;
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
// OutStreamWithCRC.h
|
||||
|
||||
#ifndef __OUT_STREAM_WITH_CRC_H
|
||||
#define __OUT_STREAM_WITH_CRC_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../IStream.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../../C/7zCrc.h"
|
||||
}
|
||||
|
||||
class COutStreamWithCRC:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> _stream;
|
||||
UInt64 _size;
|
||||
UInt32 _crc;
|
||||
bool _calculate;
|
||||
public:
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
|
||||
void ReleaseStream() { _stream.Release(); }
|
||||
void Init(bool calculate = true)
|
||||
{
|
||||
_size = 0;
|
||||
_calculate = calculate;
|
||||
_crc = CRC_INIT_VAL;
|
||||
}
|
||||
void InitCRC() { _crc = CRC_INIT_VAL; }
|
||||
UInt64 GetSize() const { return _size; }
|
||||
UInt32 GetCRC() const { return CRC_GET_DIGEST(_crc); }
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,177 +0,0 @@
|
|||
// ParseProperties.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "ParseProperties.h"
|
||||
|
||||
#include "Common/StringToInt.h"
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
|
||||
{
|
||||
if (prop.vt == VT_UI4)
|
||||
{
|
||||
if (!name.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
resValue = prop.ulVal;
|
||||
}
|
||||
else if (prop.vt == VT_EMPTY)
|
||||
{
|
||||
if(!name.IsEmpty())
|
||||
{
|
||||
const wchar_t *start = name;
|
||||
const wchar_t *end;
|
||||
UInt64 v = ConvertStringToUInt64(start, &end);
|
||||
if (end - start != name.Length())
|
||||
return E_INVALIDARG;
|
||||
resValue = (UInt32)v;
|
||||
}
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const int kLogarithmicSizeLimit = 32;
|
||||
static const wchar_t kByteSymbol = L'B';
|
||||
static const wchar_t kKiloByteSymbol = L'K';
|
||||
static const wchar_t kMegaByteSymbol = L'M';
|
||||
|
||||
HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize)
|
||||
{
|
||||
UString srcString = srcStringSpec;
|
||||
srcString.MakeUpper();
|
||||
|
||||
const wchar_t *start = srcString;
|
||||
const wchar_t *end;
|
||||
UInt64 number = ConvertStringToUInt64(start, &end);
|
||||
int numDigits = (int)(end - start);
|
||||
if (numDigits == 0 || srcString.Length() > numDigits + 1)
|
||||
return E_INVALIDARG;
|
||||
if (srcString.Length() == numDigits)
|
||||
{
|
||||
if (number >= kLogarithmicSizeLimit)
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UInt32)1 << (int)number;
|
||||
return S_OK;
|
||||
}
|
||||
switch (srcString[numDigits])
|
||||
{
|
||||
case kByteSymbol:
|
||||
if (number >= ((UInt64)1 << kLogarithmicSizeLimit))
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UInt32)number;
|
||||
break;
|
||||
case kKiloByteSymbol:
|
||||
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UInt32)(number << 10);
|
||||
break;
|
||||
case kMegaByteSymbol:
|
||||
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))
|
||||
return E_INVALIDARG;
|
||||
dicSize = (UInt32)(number << 20);
|
||||
break;
|
||||
default:
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
|
||||
{
|
||||
if (name.IsEmpty())
|
||||
{
|
||||
if (prop.vt == VT_UI4)
|
||||
{
|
||||
UInt32 logDicSize = prop.ulVal;
|
||||
if (logDicSize >= 32)
|
||||
return E_INVALIDARG;
|
||||
resValue = (UInt32)1 << logDicSize;
|
||||
return S_OK;
|
||||
}
|
||||
if (prop.vt == VT_BSTR)
|
||||
return ParsePropDictionaryValue(prop.bstrVal, resValue);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
return ParsePropDictionaryValue(name, resValue);
|
||||
}
|
||||
|
||||
bool StringToBool(const UString &s, bool &res)
|
||||
{
|
||||
if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0 || s.Compare(L"+") == 0)
|
||||
{
|
||||
res = true;
|
||||
return true;
|
||||
}
|
||||
if (s.CompareNoCase(L"OFF") == 0 || s.Compare(L"-") == 0)
|
||||
{
|
||||
res = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
|
||||
{
|
||||
switch(value.vt)
|
||||
{
|
||||
case VT_EMPTY:
|
||||
dest = true;
|
||||
return S_OK;
|
||||
case VT_BOOL:
|
||||
dest = (value.boolVal != VARIANT_FALSE);
|
||||
return S_OK;
|
||||
/*
|
||||
case VT_UI4:
|
||||
dest = (value.ulVal != 0);
|
||||
break;
|
||||
*/
|
||||
case VT_BSTR:
|
||||
return StringToBool(value.bstrVal, dest) ? S_OK : E_INVALIDARG;
|
||||
}
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
int ParseStringToUInt32(const UString &srcString, UInt32 &number)
|
||||
{
|
||||
const wchar_t *start = srcString;
|
||||
const wchar_t *end;
|
||||
UInt64 number64 = ConvertStringToUInt64(start, &end);
|
||||
if (number64 > 0xFFFFFFFF)
|
||||
{
|
||||
number = 0;
|
||||
return 0;
|
||||
}
|
||||
number = (UInt32)number64;
|
||||
return (int)(end - start);
|
||||
}
|
||||
|
||||
HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
|
||||
{
|
||||
if (name.IsEmpty())
|
||||
{
|
||||
switch(prop.vt)
|
||||
{
|
||||
case VT_UI4:
|
||||
numThreads = prop.ulVal;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
bool val;
|
||||
RINOK(SetBoolProperty(val, prop));
|
||||
numThreads = (val ? defaultNumThreads : 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 number;
|
||||
int index = ParseStringToUInt32(name, number);
|
||||
if (index != name.Length())
|
||||
return E_INVALIDARG;
|
||||
numThreads = number;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
// ParseProperties.h
|
||||
|
||||
#ifndef __PARSEPROPERTIES_H
|
||||
#define __PARSEPROPERTIES_H
|
||||
|
||||
#include "Common/MyString.h"
|
||||
#include "Common/Types.h"
|
||||
|
||||
HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
|
||||
HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize);
|
||||
HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
|
||||
|
||||
bool StringToBool(const UString &s, bool &res);
|
||||
HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value);
|
||||
int ParseStringToUInt32(const UString &srcString, UInt32 &number);
|
||||
HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
|
||||
|
||||
#endif
|
|
@ -1,9 +0,0 @@
|
|||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/MyWindows.h"
|
||||
#include "../../../Common/NewHandler.h"
|
||||
|
||||
#endif
|
|
@ -1,83 +0,0 @@
|
|||
// DLLExports.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../Common/MyInitGuid.h"
|
||||
#include "../../Common/ComTry.h"
|
||||
#include "../../Common/Types.h"
|
||||
#include "../../Windows/PropVariant.h"
|
||||
#if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
|
||||
extern "C"
|
||||
{
|
||||
#include "../../../C/Alloc.h"
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "IArchive.h"
|
||||
#include "../ICoder.h"
|
||||
#include "../IPassword.h"
|
||||
|
||||
HINSTANCE g_hInstance;
|
||||
#ifndef _UNICODE
|
||||
#ifdef _WIN32
|
||||
bool g_IsNT = false;
|
||||
static bool IsItWindowsNT()
|
||||
{
|
||||
OSVERSIONINFO versionInfo;
|
||||
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
|
||||
if (!::GetVersionEx(&versionInfo))
|
||||
return false;
|
||||
return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//desmume 27-jun-09 - dont want this in a static library
|
||||
//extern "C"
|
||||
//BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
//{
|
||||
// if (dwReason == DLL_PROCESS_ATTACH)
|
||||
// {
|
||||
// g_hInstance = hInstance;
|
||||
// #ifndef _UNICODE
|
||||
// #ifdef _WIN32
|
||||
// g_IsNT = IsItWindowsNT();
|
||||
// #endif
|
||||
// #endif
|
||||
// }
|
||||
// return TRUE;
|
||||
//}
|
||||
|
||||
DEFINE_GUID(CLSID_CArchiveHandler,
|
||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
|
||||
|
||||
static const UInt16 kDecodeId = 0x2790;
|
||||
|
||||
DEFINE_GUID(CLSID_CCodec,
|
||||
0x23170F69, 0x40C1, kDecodeId, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject);
|
||||
STDAPI CreateArchiver(const GUID *classID, const GUID *iid, void **outObject);
|
||||
|
||||
STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
|
||||
{
|
||||
// COM_TRY_BEGIN
|
||||
*outObject = 0;
|
||||
if (*iid == IID_ICompressCoder || *iid == IID_ICompressCoder2 || *iid == IID_ICompressFilter)
|
||||
{
|
||||
return CreateCoder(clsid, iid, outObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CreateArchiver(clsid, iid, outObject);
|
||||
}
|
||||
// COM_TRY_END
|
||||
}
|
||||
|
||||
STDAPI SetLargePageMode()
|
||||
{
|
||||
#if defined(_WIN32) && defined(_7ZIP_LARGE_PAGES)
|
||||
SetLargePageSize();
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
|
@ -1,284 +0,0 @@
|
|||
// GZipHandler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "GZipHandler.h"
|
||||
|
||||
#include "Common/Defs.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "Common/ComTry.h"
|
||||
#include "Windows/PropVariant.h"
|
||||
#include "Windows/Time.h"
|
||||
|
||||
#include "../../ICoder.h"
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/CreateCoder.h"
|
||||
#include "../Common/OutStreamWithCRC.h"
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
namespace NArchive {
|
||||
namespace NGZip {
|
||||
|
||||
static const CMethodId kMethodId_Deflate = 0x040108;
|
||||
|
||||
const wchar_t *kHostOS[] =
|
||||
{
|
||||
L"FAT",
|
||||
L"AMIGA",
|
||||
L"VMS",
|
||||
L"Unix",
|
||||
L"VM_CMS",
|
||||
L"Atari", // what if it's a minix filesystem? [cjh]
|
||||
L"HPFS", // filesystem used by OS/2 (and NT 3.x)
|
||||
L"Mac",
|
||||
L"Z_System",
|
||||
L"CPM",
|
||||
L"TOPS20", // pkzip 2.50 NTFS
|
||||
L"NTFS", // filesystem used by Windows NT
|
||||
L"QDOS ", // SMS/QDOS
|
||||
L"Acorn", // Archimedes Acorn RISC OS
|
||||
L"VFAT", // filesystem used by Windows 95, NT
|
||||
L"MVS",
|
||||
L"BeOS", // hybrid POSIX/database filesystem
|
||||
// BeBOX or PowerMac
|
||||
L"Tandem",
|
||||
L"THEOS"
|
||||
};
|
||||
|
||||
static const int kNumHostOSes = sizeof(kHostOS) / sizeof(kHostOS[0]);
|
||||
|
||||
static const wchar_t *kUnknownOS = L"Unknown";
|
||||
|
||||
/*
|
||||
enum // PropID
|
||||
{
|
||||
kpidExtraIsPresent = kpidUserDefined,
|
||||
kpidExtraFlags,
|
||||
kpidIsText
|
||||
};
|
||||
*/
|
||||
|
||||
STATPROPSTG kProps[] =
|
||||
{
|
||||
{ NULL, kpidPath, VT_BSTR},
|
||||
{ NULL, kpidSize, VT_UI8},
|
||||
{ NULL, kpidPackSize, VT_UI8},
|
||||
{ NULL, kpidMTime, VT_FILETIME},
|
||||
// { NULL, kpidMethod, VT_UI1},
|
||||
{ NULL, kpidHostOS, VT_BSTR},
|
||||
{ NULL, kpidCRC, VT_UI4}
|
||||
// { L"Extra", kpidExtraIsPresent, VT_BOOL}
|
||||
// { L"Extra flags", kpidExtraFlags, VT_UI1},
|
||||
// { L"Is Text", kpidIsText, VT_BOOL},
|
||||
};
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps_NO
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
*numItems = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidPath:
|
||||
if (m_Item.NameIsPresent())
|
||||
prop = MultiByteToUnicodeString(m_Item.Name, CP_ACP);
|
||||
break;
|
||||
case kpidMTime:
|
||||
{
|
||||
FILETIME utcTime;
|
||||
if (m_Item.Time != 0)
|
||||
{
|
||||
NTime::UnixTimeToFileTime((UInt32)m_Item.Time, utcTime);
|
||||
prop = utcTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
// utcTime.dwLowDateTime = utcTime.dwHighDateTime = 0;
|
||||
// prop = utcTime;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kpidSize: prop = UInt64(m_Item.UnPackSize32); break;
|
||||
case kpidPackSize: prop = m_PackSize; break;
|
||||
case kpidCommented: prop = m_Item.CommentIsPresent(); break;
|
||||
case kpidHostOS:
|
||||
prop = (m_Item.HostOS < kNumHostOSes) ?
|
||||
kHostOS[m_Item.HostOS] : kUnknownOS;
|
||||
break;
|
||||
case kpidMethod: prop = m_Item.CompressionMethod; break;
|
||||
case kpidCRC: prop = m_Item.FileCRC; break;
|
||||
/*
|
||||
case kpidExtraFlags: prop = m_Item.ExtraFlags; break;
|
||||
case kpidIsText: prop = m_Item.IsText(); break;
|
||||
case kpidExtraIsPresent: prop = m_Item.ExtraFieldIsPresent(); break;
|
||||
*/
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
const UInt64 * /* maxCheckStartPosition */,
|
||||
IArchiveOpenCallback * /* openArchiveCallback */)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
try
|
||||
{
|
||||
CInArchive archive;
|
||||
RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_StreamStartPosition));
|
||||
RINOK(archive.ReadHeader(inStream, m_Item));
|
||||
m_DataOffset = archive.GetOffset();
|
||||
UInt64 newPosition;
|
||||
RINOK(inStream->Seek(-8, STREAM_SEEK_END, &newPosition));
|
||||
m_PackSize = newPosition - (m_StreamStartPosition + m_DataOffset);
|
||||
if (archive.ReadPostHeader(inStream, m_Item) != S_OK)
|
||||
return S_FALSE;
|
||||
m_Stream = inStream;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
m_Stream.Release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool allFilesMode = (numItems == UInt32(-1));
|
||||
if (!allFilesMode)
|
||||
{
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
if (numItems != 1)
|
||||
return E_INVALIDARG;
|
||||
if (indices[0] != 0)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
bool testMode = (_aTestMode != 0);
|
||||
|
||||
extractCallback->SetTotal(m_PackSize);
|
||||
|
||||
UInt64 currentTotalPacked = 0;
|
||||
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalPacked));
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode;
|
||||
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
|
||||
NArchive::NExtract::NAskMode::kExtract;
|
||||
|
||||
RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
|
||||
|
||||
if(!testMode && !realOutStream)
|
||||
return S_OK;
|
||||
|
||||
extractCallback->PrepareOperation(askMode);
|
||||
|
||||
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
|
||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
||||
outStreamSpec->SetStream(realOutStream);
|
||||
outStreamSpec->Init();
|
||||
realOutStream.Release();
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, true);
|
||||
|
||||
CMyComPtr<ICompressCoder> deflateDecoder;
|
||||
bool firstItem = true;
|
||||
RINOK(m_Stream->Seek(m_StreamStartPosition, STREAM_SEEK_SET, NULL));
|
||||
Int32 opRes;
|
||||
for (;;)
|
||||
{
|
||||
lps->InSize = currentTotalPacked;
|
||||
lps->OutSize = outStreamSpec->GetSize();
|
||||
|
||||
CInArchive archive;
|
||||
CItem item;
|
||||
HRESULT result = archive.ReadHeader(m_Stream, item);
|
||||
if (result != S_OK)
|
||||
{
|
||||
if (firstItem)
|
||||
return E_FAIL;
|
||||
opRes = NArchive::NExtract::NOperationResult::kOK;
|
||||
break;
|
||||
}
|
||||
firstItem = false;
|
||||
|
||||
UInt64 dataStartPos;
|
||||
RINOK(m_Stream->Seek(0, STREAM_SEEK_CUR, &dataStartPos));
|
||||
|
||||
outStreamSpec->InitCRC();
|
||||
|
||||
if (item.CompressionMethod != NFileHeader::NCompressionMethod::kDeflate)
|
||||
{
|
||||
opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!deflateDecoder)
|
||||
{
|
||||
RINOK(CreateCoder(
|
||||
EXTERNAL_CODECS_VARS
|
||||
kMethodId_Deflate, deflateDecoder, false));
|
||||
if (!deflateDecoder)
|
||||
{
|
||||
opRes = NArchive::NExtract::NOperationResult::kUnSupportedMethod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = deflateDecoder->Code(m_Stream, outStream, NULL, NULL, progress);
|
||||
if (result != S_OK)
|
||||
{
|
||||
if (result != S_FALSE)
|
||||
return result;
|
||||
opRes = NArchive::NExtract::NOperationResult::kDataError;
|
||||
break;
|
||||
}
|
||||
|
||||
CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
|
||||
RINOK(deflateDecoder.QueryInterface(IID_ICompressGetInStreamProcessedSize,
|
||||
&getInStreamProcessedSize));
|
||||
UInt64 packSize;
|
||||
RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&packSize));
|
||||
UInt64 pos;
|
||||
RINOK(m_Stream->Seek(dataStartPos + packSize, STREAM_SEEK_SET, &pos));
|
||||
|
||||
currentTotalPacked = pos - m_StreamStartPosition;
|
||||
|
||||
CItem postItem;
|
||||
if (archive.ReadPostHeader(m_Stream, postItem) != S_OK)
|
||||
return E_FAIL;
|
||||
if((outStreamSpec->GetCRC() != postItem.FileCRC))
|
||||
{
|
||||
opRes = NArchive::NExtract::NOperationResult::kCRCError;
|
||||
break;
|
||||
}
|
||||
}
|
||||
outStream.Release();
|
||||
return extractCallback->SetOperationResult(opRes);
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
IMPL_ISetCompressCodecsInfo
|
||||
|
||||
}}
|
|
@ -1,65 +0,0 @@
|
|||
// GZip/Handler.h
|
||||
|
||||
#ifndef __GZIP_HANDLER_H
|
||||
#define __GZIP_HANDLER_H
|
||||
|
||||
#include "Common/MyCom.h"
|
||||
|
||||
#include "../IArchive.h"
|
||||
|
||||
#include "../../Common/CreateCoder.h"
|
||||
|
||||
#include "GZipIn.h"
|
||||
#include "GZipUpdate.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NGZip {
|
||||
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
public IOutArchive,
|
||||
public ISetProperties,
|
||||
PUBLIC_ISetCompressCodecsInfo
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_QUERYINTERFACE_BEGIN2(IInArchive)
|
||||
MY_QUERYINTERFACE_ENTRY(IOutArchive)
|
||||
MY_QUERYINTERFACE_ENTRY(ISetProperties)
|
||||
QUERY_ENTRY_ISetCompressCodecsInfo
|
||||
MY_QUERYINTERFACE_END
|
||||
MY_ADDREF_RELEASE
|
||||
|
||||
INTERFACE_IInArchive(;)
|
||||
#ifndef EXTRACT_ONLY
|
||||
INTERFACE_IOutArchive(;)
|
||||
|
||||
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
|
||||
#endif
|
||||
|
||||
DECL_ISetCompressCodecsInfo
|
||||
|
||||
CHandler() { InitMethodProperties(); }
|
||||
|
||||
private:
|
||||
NArchive::NGZip::CItem m_Item;
|
||||
UInt64 m_StreamStartPosition;
|
||||
UInt64 m_DataOffset;
|
||||
UInt64 m_PackSize;
|
||||
CMyComPtr<IInStream> m_Stream;
|
||||
CCompressionMethodMode m_Method;
|
||||
UInt32 m_Level;
|
||||
|
||||
DECL_EXTERNAL_CODECS_VARS
|
||||
|
||||
void InitMethodProperties()
|
||||
{
|
||||
m_Method.NumMatchFinderCyclesDefined = false;
|
||||
m_Level = m_Method.NumPasses = m_Method.NumFastBytes =
|
||||
m_Method.NumMatchFinderCycles = m_Method.Algo = 0xFFFFFFFF;
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
|
@ -1,20 +0,0 @@
|
|||
// Archive/GZip/Header.h
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "GZipHeader.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NGZip {
|
||||
|
||||
extern UInt16 kSignature = 0x8B1F + 1;
|
||||
|
||||
class CMarkersInitializer
|
||||
{
|
||||
public:
|
||||
CMarkersInitializer()
|
||||
{ kSignature--; }
|
||||
} g_MarkerInitializer;
|
||||
|
||||
}}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
// Archive/GZip/Header.h
|
||||
|
||||
#ifndef __ARCHIVE_GZIP_HEADER_H
|
||||
#define __ARCHIVE_GZIP_HEADER_H
|
||||
|
||||
#include "Common/Types.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NGZip {
|
||||
|
||||
extern UInt16 kSignature;
|
||||
static const UInt32 kSignatureSize = 2;
|
||||
|
||||
namespace NFileHeader
|
||||
{
|
||||
/*
|
||||
struct CBlock
|
||||
{
|
||||
UInt16 Id;
|
||||
Byte CompressionMethod;
|
||||
Byte Flags;
|
||||
UInt32 Time;
|
||||
Byte ExtraFlags;
|
||||
Byte HostOS;
|
||||
};
|
||||
*/
|
||||
|
||||
namespace NFlags
|
||||
{
|
||||
const int kDataIsText = 1 << 0;
|
||||
const int kHeaderCRCIsPresent = 1 << 1;
|
||||
const int kExtraIsPresent = 1 << 2;
|
||||
const int kNameIsPresent = 1 << 3;
|
||||
const int kComentIsPresent = 1 << 4;
|
||||
}
|
||||
|
||||
namespace NExtraFlags
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kMaximum = 2,
|
||||
kFastest = 4
|
||||
};
|
||||
}
|
||||
|
||||
namespace NCompressionMethod
|
||||
{
|
||||
const Byte kDeflate = 8;
|
||||
}
|
||||
|
||||
namespace NHostOS
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kFAT = 0, // filesystem used by MS-DOS, OS/2, Win32
|
||||
// pkzip 2.50 (FAT / VFAT / FAT32 file systems)
|
||||
kAMIGA = 1,
|
||||
kVMS = 2, // VAX/VMS
|
||||
kUnix = 3,
|
||||
kVM_CMS = 4,
|
||||
kAtari = 5, // what if it's a minix filesystem? [cjh]
|
||||
kHPFS = 6, // filesystem used by OS/2 (and NT 3.x)
|
||||
kMac = 7,
|
||||
kZ_System = 8,
|
||||
kCPM = 9,
|
||||
kTOPS20 = 10, // pkzip 2.50 NTFS
|
||||
kNTFS = 11, // filesystem used by Windows NT
|
||||
kQDOS = 12, // SMS/QDOS
|
||||
kAcorn = 13, // Archimedes Acorn RISC OS
|
||||
kVFAT = 14, // filesystem used by Windows 95, NT
|
||||
kMVS = 15,
|
||||
kBeOS = 16, // hybrid POSIX/database filesystem
|
||||
// BeBOX or PowerMac
|
||||
kTandem = 17,
|
||||
kTHEOS = 18,
|
||||
|
||||
kUnknown = 255
|
||||
};
|
||||
const int kNumHostSystems = 19;
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue