Removed ancient LZMA SDK.

This commit is contained in:
Ryan C. Gordon 2017-07-17 12:20:14 -04:00
parent a5d3dd498e
commit da1561a09f
426 changed files with 0 additions and 59760 deletions

View File

@ -1,237 +0,0 @@
7z ANSI-C Decoder 4.48
----------------------
7z ANSI-C Decoder 4.48 Copyright (C) 1999-2006 Igor Pavlov
7z ANSI-C provides 7z/LZMA decoding.
7z ANSI-C version is simplified version ported from C++ code.
LZMA is default and general compression method of 7z format
in 7-Zip compression program (www.7-zip.org). LZMA provides high
compression ratio and very fast decompression.
LICENSE
-------
Read lzma.txt for information about license.
Files
---------------------
7zAlloc.* - Allocate and Free
7zBuffer.* - Buffer structure
7zCrc.* - CRC32 code
7zDecode.* - Low level memory->memory decoding
7zExtract.* - High level stream->memory decoding
7zHeader.* - .7z format constants
7zIn.* - .7z archive opening
7zItem.* - .7z structures
7zMain.c - Test application
7zMethodID.* - MethodID structure
7zTypes.h - Base types and constants
How To Use
----------
You must download 7-Zip program from www.7-zip.org.
You can create .7z archive with 7z.exe or 7za.exe:
7za.exe a archive.7z *.htm -r -mx -m0fb=255
If you have big number of files in archive, and you need fast extracting,
you can use partly-solid archives:
7za.exe a archive.7z *.htm -ms=512K -r -mx -m0fb=255 -m0d=512K
In that example 7-Zip will use 512KB solid blocks. So it needs to decompress only
512KB for extracting one file from such archive.
Limitations of current version of 7z ANSI-C Decoder
---------------------------------------------------
- It reads only "FileName", "Size", "LastWriteTime" and "CRC" information for each file in archive.
- It supports only LZMA and Copy (no compression) methods with BCJ or BCJ2 filters.
- It converts original UTF-16 Unicode file names to UTF-8 Unicode file names.
These limitations will be fixed in future versions.
Using 7z ANSI-C Decoder Test application:
-----------------------------------------
Usage: 7zDec <command> <archive_name>
<Command>:
e: Extract files from archive
l: List contents of archive
t: Test integrity of archive
Example:
7zDec l archive.7z
lists contents of archive.7z
7zDec e archive.7z
extracts files from archive.7z to current folder.
How to use .7z Decoder
----------------------
.7z Decoder can be compiled in one of two modes:
1) Default mode. In that mode 7z Decoder will read full compressed
block to RAM before decompressing.
2) Mode with defined _LZMA_IN_CB. In that mode 7z Decoder can read
compressed block by parts. And you can specify desired buffer size.
So memory requirements can be reduced. But decompressing speed will
be 5-10% lower and code size is slightly larger.
Memory allocation
~~~~~~~~~~~~~~~~~
7z Decoder uses two memory pools:
1) Temporary pool
2) Main pool
Such scheme can allow you to avoid fragmentation of allocated blocks.
Steps for using 7z decoder
--------------------------
Use code at 7zMain.c as example.
1) Declare variables:
inStream /* implements ISzInStream interface */
CArchiveDatabaseEx db; /* 7z archive database structure */
ISzAlloc allocImp; /* memory functions for main pool */
ISzAlloc allocTempImp; /* memory functions for temporary pool */
2) call InitCrcTable(); function to initialize CRC structures.
3) call SzArDbExInit(&db); function to initialize db structures.
4) call SzArchiveOpen(inStream, &db, &allocMain, &allocTemp) to open archive
This function opens archive "inStream" and reads headers to "db".
All items in "db" will be allocated with "allocMain" functions.
SzArchiveOpen function allocates and frees temporary structures by "allocTemp" functions.
5) List items or Extract items
Listing code:
~~~~~~~~~~~~~
{
UInt32 i;
for (i = 0; i < db.Database.NumFiles; i++)
{
CFileItem *f = db.Database.Files + i;
printf("%10d %s\n", (int)f->Size, f->Name);
}
}
Extracting code:
~~~~~~~~~~~~~~~~
SZ_RESULT SzExtract(
ISzInStream *inStream,
CArchiveDatabaseEx *db,
UInt32 fileIndex, /* index of file */
UInt32 *blockIndex, /* index of solid block */
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
size_t *outBufferSize, /* buffer size for output buffer */
size_t *offset, /* offset of stream for required file in *outBuffer */
size_t *outSizeProcessed, /* size of file in *outBuffer */
ISzAlloc *allocMain,
ISzAlloc *allocTemp);
If you need to decompress more than one file, you can send these values from previous call:
blockIndex,
outBuffer,
outBufferSize,
You can consider "outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed.
After decompressing you must free "outBuffer":
allocImp.Free(outBuffer);
6) call SzArDbExFree(&db, allocImp.Free) to free allocated items in "db".
Memory requirements for .7z decoding
------------------------------------
Memory usage for Archive opening:
- Temporary pool:
- Memory for compressed .7z headers (if _LZMA_IN_CB is not defined)
- Memory for uncompressed .7z headers
- some other temporary blocks
- Main pool:
- Memory for database:
Estimated size of one file structures in solid archive:
- Size (4 or 8 Bytes)
- CRC32 (4 bytes)
- LastWriteTime (8 bytes)
- Some file information (4 bytes)
- File Name (variable length) + pointer + allocation structures
Memory usage for archive Decompressing:
- Temporary pool:
- Memory for compressed solid block (if _LZMA_IN_CB is not defined)
- Memory for LZMA decompressing structures
- Main pool:
- Memory for decompressed solid block
- Memory for temprorary buffers, if BCJ2 fileter is used. Usually these
temprorary buffers can be about 15% of solid block size.
If _LZMA_IN_CB is defined, 7z Decoder will not allocate memory for
compressed blocks. Instead of this, you must allocate buffer with desired
size before calling 7z Decoder. Use 7zMain.c as example.
EXIT codes
-----------
7z Decoder functions can return one of the following codes:
#define SZ_OK (0)
#define SZE_DATA_ERROR (1)
#define SZE_OUTOFMEMORY (2)
#define SZE_CRC_ERROR (3)
#define SZE_NOTIMPL (4)
#define SZE_FAIL (5)
#define SZE_ARCHIVE_ERROR (6)
LZMA Defines
------------
_LZMA_IN_CB - Use special callback mode for input stream to reduce memory requirements
_SZ_FILE_SIZE_32 - define it if you need only support for files smaller than 4 GB
_SZ_NO_INT_64 - define it if your compiler doesn't support long long int or __int64.
_LZMA_PROB32 - it can increase LZMA decompressing speed on some 32-bit CPUs.
_SZ_ALLOC_DEBUG - define it if you want to debug alloc/free operations to stderr.
---
http://www.7-zip.org
http://www.7-zip.org/support.html

View File

@ -1,471 +0,0 @@
7z Format description (2.30 Beta 25)
-----------------------------------
This file contains description of 7z archive format.
7z archive can contain files compressed with any method.
See "Methods.txt" for description for defined compressing methods.
Format structure Overview
-------------------------
Some fields can be optional.
Archive structure
~~~~~~~~~~~~~~~~~
SignatureHeader
[PackedStreams]
[PackedStreamsForHeaders]
[
Header
or
{
Packed Header
HeaderInfo
}
]
Header structure
~~~~~~~~~~~~~~~~
{
ArchiveProperties
AdditionalStreams
{
PackInfo
{
PackPos
NumPackStreams
Sizes[NumPackStreams]
CRCs[NumPackStreams]
}
CodersInfo
{
NumFolders
Folders[NumFolders]
{
NumCoders
CodersInfo[NumCoders]
{
ID
NumInStreams;
NumOutStreams;
PropertiesSize
Properties[PropertiesSize]
}
NumBindPairs
BindPairsInfo[NumBindPairs]
{
InIndex;
OutIndex;
}
PackedIndices
}
UnPackSize[Folders][Folders.NumOutstreams]
CRCs[NumFolders]
}
SubStreamsInfo
{
NumUnPackStreamsInFolders[NumFolders];
UnPackSizes[]
CRCs[]
}
}
MainStreamsInfo
{
(Same as in AdditionalStreams)
}
FilesInfo
{
NumFiles
Properties[]
{
ID
Size
Data
}
}
}
HeaderInfo structure
~~~~~~~~~~~~~~~~~~~~
{
(Same as in AdditionalStreams)
}
Notes about Notation and encoding
---------------------------------
7z uses little endian encoding.
7z archive format has optional headers that are marked as
[]
Header
[]
REAL_UINT64 means real UINT64.
UINT64 means real UINT64 encoded with the following scheme:
Size of encoding sequence depends from first byte:
First_Byte Extra_Bytes Value
(binary)
0xxxxxxx : ( xxxxxxx )
10xxxxxx BYTE y[1] : ( xxxxxx << (8 * 1)) + y
110xxxxx BYTE y[2] : ( xxxxx << (8 * 2)) + y
...
1111110x BYTE y[6] : ( x << (8 * 6)) + y
11111110 BYTE y[7] : y
11111111 BYTE y[8] : y
Property IDs
------------
0x00 = kEnd,
0x01 = kHeader,
0x02 = kArchiveProperties,
0x03 = kAdditionalStreamsInfo,
0x04 = kMainStreamsInfo,
0x05 = kFilesInfo,
0x06 = kPackInfo,
0x07 = kUnPackInfo,
0x08 = kSubStreamsInfo,
0x09 = kSize,
0x0A = kCRC,
0x0B = kFolder,
0x0C = kCodersUnPackSize,
0x0D = kNumUnPackStream,
0x0E = kEmptyStream,
0x0F = kEmptyFile,
0x10 = kAnti,
0x11 = kName,
0x12 = kCreationTime,
0x13 = kLastAccessTime,
0x14 = kLastWriteTime,
0x15 = kWinAttributes,
0x16 = kComment,
0x17 = kEncodedHeader,
7z format headers
-----------------
SignatureHeader
~~~~~~~~~~~~~~~
BYTE kSignature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
ArchiveVersion
{
BYTE Major; // now = 0
BYTE Minor; // now = 2
};
UINT32 StartHeaderCRC;
StartHeader
{
REAL_UINT64 NextHeaderOffset
REAL_UINT64 NextHeaderSize
UINT32 NextHeaderCRC
}
...........................
ArchiveProperties
~~~~~~~~~~~~~~~~~
BYTE NID::kArchiveProperties (0x02)
for (;;)
{
BYTE PropertyType;
if (aType == 0)
break;
UINT64 PropertySize;
BYTE PropertyData[PropertySize];
}
Digests (NumStreams)
~~~~~~~~~~~~~~~~~~~~~
BYTE AllAreDefined
if (AllAreDefined == 0)
{
for(NumStreams)
BIT Defined
}
UINT32 CRCs[NumDefined]
PackInfo
~~~~~~~~~~~~
BYTE NID::kPackInfo (0x06)
UINT64 PackPos
UINT64 NumPackStreams
[]
BYTE NID::kSize (0x09)
UINT64 PackSizes[NumPackStreams]
[]
[]
BYTE NID::kCRC (0x0A)
PackStreamDigests[NumPackStreams]
[]
BYTE NID::kEnd
Folder
~~~~~~
UINT64 NumCoders;
for (NumCoders)
{
BYTE
{
0:3 DecompressionMethod.IDSize
4:
0 - IsSimple
1 - Is not simple
5:
0 - No Attributes
1 - There Are Attributes
7:
0 - Last Method in Alternative_Method_List
1 - There are more alternative methods
}
BYTE DecompressionMethod.ID[DecompressionMethod.IDSize]
if (!IsSimple)
{
UINT64 NumInStreams;
UINT64 NumOutStreams;
}
if (DecompressionMethod[0] != 0)
{
UINT64 PropertiesSize
BYTE Properties[PropertiesSize]
}
}
NumBindPairs = NumOutStreamsTotal - 1;
for (NumBindPairs)
{
UINT64 InIndex;
UINT64 OutIndex;
}
NumPackedStreams = NumInStreamsTotal - NumBindPairs;
if (NumPackedStreams > 1)
for(NumPackedStreams)
{
UINT64 Index;
};
Coders Info
~~~~~~~~~~~
BYTE NID::kUnPackInfo (0x07)
BYTE NID::kFolder (0x0B)
UINT64 NumFolders
BYTE External
switch(External)
{
case 0:
Folders[NumFolders]
case 1:
UINT64 DataStreamIndex
}
BYTE ID::kCodersUnPackSize (0x0C)
for(Folders)
for(Folder.NumOutStreams)
UINT64 UnPackSize;
[]
BYTE NID::kCRC (0x0A)
UnPackDigests[NumFolders]
[]
BYTE NID::kEnd
SubStreams Info
~~~~~~~~~~~~~~
BYTE NID::kSubStreamsInfo; (0x08)
[]
BYTE NID::kNumUnPackStream; (0x0D)
UINT64 NumUnPackStreamsInFolders[NumFolders];
[]
[]
BYTE NID::kSize (0x09)
UINT64 UnPackSizes[]
[]
[]
BYTE NID::kCRC (0x0A)
Digests[Number of streams with unknown CRC]
[]
BYTE NID::kEnd
Streams Info
~~~~~~~~~~~~
[]
PackInfo
[]
[]
CodersInfo
[]
[]
SubStreamsInfo
[]
BYTE NID::kEnd
FilesInfo
~~~~~~~~~
BYTE NID::kFilesInfo; (0x05)
UINT64 NumFiles
for (;;)
{
BYTE PropertyType;
if (aType == 0)
break;
UINT64 Size;
switch(PropertyType)
{
kEmptyStream: (0x0E)
for(NumFiles)
BIT IsEmptyStream
kEmptyFile: (0x0F)
for(EmptyStreams)
BIT IsEmptyFile
kAnti: (0x10)
for(EmptyStreams)
BIT IsAntiFile
case kCreationTime: (0x12)
case kLastAccessTime: (0x13)
case kLastWriteTime: (0x14)
BYTE AllAreDefined
if (AllAreDefined == 0)
{
for(NumFiles)
BIT TimeDefined
}
BYTE External;
if(External != 0)
UINT64 DataIndex
[]
for(Definded Items)
UINT32 Time
[]
kNames: (0x11)
BYTE External;
if(External != 0)
UINT64 DataIndex
[]
for(Files)
{
wchar_t Names[NameSize];
wchar_t 0;
}
[]
kAttributes: (0x15)
BYTE AllAreDefined
if (AllAreDefined == 0)
{
for(NumFiles)
BIT AttributesAreDefined
}
BYTE External;
if(External != 0)
UINT64 DataIndex
[]
for(Definded Attributes)
UINT32 Attributes
[]
}
}
Header
~~~~~~
BYTE NID::kHeader (0x01)
[]
ArchiveProperties
[]
[]
BYTE NID::kAdditionalStreamsInfo; (0x03)
StreamsInfo
[]
[]
BYTE NID::kMainStreamsInfo; (0x04)
StreamsInfo
[]
[]
FilesInfo
[]
BYTE NID::kEnd
HeaderInfo
~~~~~~~~~~
[]
BYTE NID::kEncodedHeader; (0x17)
StreamsInfo for Encoded Header
[]
---
End of document

View File

@ -1,32 +0,0 @@
/* 7zCrc.c */
#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;
}

View File

@ -1,21 +0,0 @@
/* 7zCrc.h */
#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

View File

@ -1,40 +0,0 @@
/* 7zCrcT8.c */
#include "7zCrc.h"
#define kCrcPoly 0xEDB88320
#define CRC_NUM_TABLES 8
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
void MY_FAST_CALL CrcGenerateTable()
{
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;
}
#if CRC_NUM_TABLES > 1
for (; i < 256 * CRC_NUM_TABLES; i++)
{
UInt32 r = g_CrcTable[i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
}
#endif
}
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
{
return CrcUpdateT8(v, data, size, g_CrcTable);
}
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
{
return CrcUpdateT8(CRC_INIT_VAL, data, size, g_CrcTable) ^ 0xFFFFFFFF;
}

View File

@ -1,119 +0,0 @@
/* Alloc.c */
#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
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount++);
#endif
return malloc(size);
}
void MyFree(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
fprintf(stderr, "\nFree; count = %10d", --g_allocCount);
#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

View File

@ -1,29 +0,0 @@
/* Alloc.h */
#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

View File

@ -1,70 +0,0 @@
/* 7zAlloc.c */
#include <stdlib.h>
#include "7zAlloc.h"
/* #define _SZ_ALLOC_DEBUG */
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
#ifdef _SZ_ALLOC_DEBUG
#ifdef _WIN32
#include <windows.h>
#endif
#include <stdio.h>
int g_allocCount = 0;
int g_allocCountTemp = 0;
#endif
void *SzAlloc(size_t size)
{
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount);
g_allocCount++;
#endif
return malloc(size);
}
void SzFree(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
{
g_allocCount--;
fprintf(stderr, "\nFree; count = %10d", g_allocCount);
}
#endif
free(address);
}
void *SzAllocTemp(size_t size)
{
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp);
g_allocCountTemp++;
#ifdef _WIN32
return HeapAlloc(GetProcessHeap(), 0, size);
#endif
#endif
return malloc(size);
}
void SzFreeTemp(void *address)
{
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
{
g_allocCountTemp--;
fprintf(stderr, "\nFree_temp; count = %10d", g_allocCountTemp);
}
#ifdef _WIN32
HeapFree(GetProcessHeap(), 0, address);
return;
#endif
#endif
free(address);
}

View File

@ -1,20 +0,0 @@
/* 7zAlloc.h */
#ifndef __7Z_ALLOC_H
#define __7Z_ALLOC_H
#include <stddef.h>
typedef struct _ISzAlloc
{
void *(*Alloc)(size_t size);
void (*Free)(void *address); /* address can be 0 */
} ISzAlloc;
void *SzAlloc(size_t size);
void SzFree(void *address);
void *SzAllocTemp(size_t size);
void SzFreeTemp(void *address);
#endif

View File

@ -1,29 +0,0 @@
/* 7zBuffer.c */
#include "7zBuffer.h"
#include "7zAlloc.h"
void SzByteBufferInit(CSzByteBuffer *buffer)
{
buffer->Capacity = 0;
buffer->Items = 0;
}
int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size))
{
buffer->Capacity = newCapacity;
if (newCapacity == 0)
{
buffer->Items = 0;
return 1;
}
buffer->Items = (Byte *)allocFunc(newCapacity);
return (buffer->Items != 0);
}
void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *))
{
freeFunc(buffer->Items);
buffer->Items = 0;
buffer->Capacity = 0;
}

View File

@ -1,19 +0,0 @@
/* 7zBuffer.h */
#ifndef __7Z_BUFFER_H
#define __7Z_BUFFER_H
#include <stddef.h>
#include "../../Types.h"
typedef struct _CSzByteBuffer
{
size_t Capacity;
Byte *Items;
}CSzByteBuffer;
void SzByteBufferInit(CSzByteBuffer *buffer);
int SzByteBufferCreate(CSzByteBuffer *buffer, size_t newCapacity, void * (*allocFunc)(size_t size));
void SzByteBufferFree(CSzByteBuffer *buffer, void (*freeFunc)(void *));
#endif

View File

@ -1,345 +0,0 @@
/* 7zDecode.c */
#include <memory.h>
/* BEGIN PHYSFS CHANGE */
#include <string.h>
/* END PHYSFS CHANGE */
#include "7zDecode.h"
#ifdef _SZ_ONE_DIRECTORY
#include "LzmaDecode.h"
#else
#include "../../Compress/Lzma/LzmaDecode.h"
#include "../../Compress/Branch/BranchX86.h"
#include "../../Compress/Branch/BranchX86_2.h"
#endif
#define k_Copy 0
#define k_LZMA 0x30101
#define k_BCJ 0x03030103
#define k_BCJ2 0x0303011B
#ifdef _LZMA_IN_CB
typedef struct _CLzmaInCallbackImp
{
ILzmaInCallback InCallback;
ISzInStream *InStream;
CFileSize Size;
} CLzmaInCallbackImp;
int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size)
{
CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object;
size_t processedSize;
SZ_RESULT res;
size_t curSize = (1 << 20);
if (curSize > cb->Size)
curSize = (size_t)cb->Size;
*size = 0;
res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, curSize, &processedSize);
*size = (SizeT)processedSize;
if (processedSize > curSize)
return (int)SZE_FAIL;
cb->Size -= processedSize;
if (res == SZ_OK)
return 0;
return (int)res;
}
#endif
SZ_RESULT SzDecodeLzma(CCoderInfo *coder, CFileSize inSize,
#ifdef _LZMA_IN_CB
ISzInStream *inStream,
#else
const Byte *inBuffer,
#endif
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
{
#ifdef _LZMA_IN_CB
CLzmaInCallbackImp lzmaCallback;
#else
SizeT inProcessed;
#endif
CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
int result;
SizeT outSizeProcessedLoc;
#ifdef _LZMA_IN_CB
lzmaCallback.Size = inSize;
lzmaCallback.InStream = inStream;
lzmaCallback.InCallback.Read = LzmaReadImp;
#endif
if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
(unsigned)coder->Properties.Capacity) != LZMA_RESULT_OK)
return SZE_FAIL;
state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
if (state.Probs == 0)
return SZE_OUTOFMEMORY;
#ifdef _LZMA_OUT_READ
if (state.Properties.DictionarySize == 0)
state.Dictionary = 0;
else
{
state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
if (state.Dictionary == 0)
{
allocMain->Free(state.Probs);
return SZE_OUTOFMEMORY;
}
}
LzmaDecoderInit(&state);
#endif
result = LzmaDecode(&state,
#ifdef _LZMA_IN_CB
&lzmaCallback.InCallback,
#else
inBuffer, (SizeT)inSize, &inProcessed,
#endif
outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
allocMain->Free(state.Probs);
#ifdef _LZMA_OUT_READ
allocMain->Free(state.Dictionary);
#endif
if (result == LZMA_RESULT_DATA_ERROR)
return SZE_DATA_ERROR;
if (result != LZMA_RESULT_OK)
return SZE_FAIL;
return (outSizeProcessedLoc == outSize) ? SZ_OK : SZE_DATA_ERROR;
}
#ifdef _LZMA_IN_CB
SZ_RESULT SzDecodeCopy(CFileSize inSize, ISzInStream *inStream, Byte *outBuffer)
{
while (inSize > 0)
{
void *inBuffer;
size_t processedSize, curSize = (1 << 18);
if (curSize > inSize)
curSize = (size_t)(inSize);
RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, curSize, &processedSize));
if (processedSize == 0)
return SZE_DATA_ERROR;
if (processedSize > curSize)
return SZE_FAIL;
memcpy(outBuffer, inBuffer, processedSize);
outBuffer += processedSize;
inSize -= processedSize;
}
return SZ_OK;
}
#endif
#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA)
#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1)
#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1)
#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1)
SZ_RESULT CheckSupportedFolder(const CFolder *f)
{
if (f->NumCoders < 1 || f->NumCoders > 4)
return SZE_NOTIMPL;
if (IS_UNSUPPORTED_CODER(f->Coders[0]))
return SZE_NOTIMPL;
if (f->NumCoders == 1)
{
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
return SZE_NOTIMPL;
return SZ_OK;
}
if (f->NumCoders == 2)
{
if (IS_NO_BCJ(f->Coders[1]) ||
f->NumPackStreams != 1 || f->PackStreams[0] != 0 ||
f->NumBindPairs != 1 ||
f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0)
return SZE_NOTIMPL;
return SZ_OK;
}
if (f->NumCoders == 4)
{
if (IS_UNSUPPORTED_CODER(f->Coders[1]) ||
IS_UNSUPPORTED_CODER(f->Coders[2]) ||
IS_NO_BCJ2(f->Coders[3]))
return SZE_NOTIMPL;
if (f->NumPackStreams != 4 ||
f->PackStreams[0] != 2 ||
f->PackStreams[1] != 6 ||
f->PackStreams[2] != 1 ||
f->PackStreams[3] != 0 ||
f->NumBindPairs != 3 ||
f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
return SZE_NOTIMPL;
return SZ_OK;
}
return SZE_NOTIMPL;
}
CFileSize GetSum(const CFileSize *values, UInt32 index)
{
CFileSize sum = 0;
UInt32 i;
for (i = 0; i < index; i++)
sum += values[i];
return sum;
}
SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder,
#ifdef _LZMA_IN_CB
ISzInStream *inStream, CFileSize startPos,
#else
const Byte *inBuffer,
#endif
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain,
Byte *tempBuf[])
{
UInt32 ci;
size_t tempSizes[3] = { 0, 0, 0};
size_t tempSize3 = 0;
Byte *tempBuf3 = 0;
RINOK(CheckSupportedFolder(folder));
for (ci = 0; ci < folder->NumCoders; ci++)
{
CCoderInfo *coder = &folder->Coders[ci];
if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA)
{
UInt32 si = 0;
CFileSize offset;
CFileSize inSize;
Byte *outBufCur = outBuffer;
size_t outSizeCur = outSize;
if (folder->NumCoders == 4)
{
UInt32 indices[] = { 3, 2, 0 };
CFileSize unpackSize = folder->UnPackSizes[ci];
si = indices[ci];
if (ci < 2)
{
Byte *temp;
outSizeCur = (size_t)unpackSize;
if (outSizeCur != unpackSize)
return SZE_OUTOFMEMORY;
temp = (Byte *)allocMain->Alloc(outSizeCur);
if (temp == 0 && outSizeCur != 0)
return SZE_OUTOFMEMORY;
outBufCur = tempBuf[1 - ci] = temp;
tempSizes[1 - ci] = outSizeCur;
}
else if (ci == 2)
{
if (unpackSize > outSize)
return SZE_OUTOFMEMORY;
tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
tempSize3 = outSizeCur = (size_t)unpackSize;
}
else
return SZE_NOTIMPL;
}
offset = GetSum(packSizes, si);
inSize = packSizes[si];
#ifdef _LZMA_IN_CB
RINOK(inStream->Seek(inStream, startPos + offset));
#endif
if (coder->MethodID == k_Copy)
{
if (inSize != outSizeCur)
return SZE_DATA_ERROR;
#ifdef _LZMA_IN_CB
RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
#else
memcpy(outBufCur, inBuffer + (size_t)offset, (size_t)inSize);
#endif
}
else
{
SZ_RESULT res = SzDecodeLzma(coder, inSize,
#ifdef _LZMA_IN_CB
inStream,
#else
inBuffer + (size_t)offset,
#endif
outBufCur, outSizeCur, allocMain);
RINOK(res)
}
}
else if (coder->MethodID == k_BCJ)
{
UInt32 state;
if (ci != 1)
return SZE_NOTIMPL;
x86_Convert_Init(state);
x86_Convert(outBuffer, outSize, 0, &state, 0);
}
else if (coder->MethodID == k_BCJ2)
{
CFileSize offset = GetSum(packSizes, 1);
CFileSize s3Size = packSizes[1];
SZ_RESULT res;
if (ci != 3)
return SZE_NOTIMPL;
#ifdef _LZMA_IN_CB
RINOK(inStream->Seek(inStream, startPos + offset));
tempSizes[2] = (size_t)s3Size;
if (tempSizes[2] != s3Size)
return SZE_OUTOFMEMORY;
tempBuf[2] = (Byte *)allocMain->Alloc(tempSizes[2]);
if (tempBuf[2] == 0 && tempSizes[2] != 0)
return SZE_OUTOFMEMORY;
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
RINOK(res)
#endif
res = x86_2_Decode(
tempBuf3, tempSize3,
tempBuf[0], tempSizes[0],
tempBuf[1], tempSizes[1],
#ifdef _LZMA_IN_CB
tempBuf[2], tempSizes[2],
#else
inBuffer + (size_t)offset, (size_t)s3Size,
#endif
outBuffer, outSize);
RINOK(res)
}
else
return SZE_NOTIMPL;
}
return SZ_OK;
}
SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
#ifdef _LZMA_IN_CB
ISzInStream *inStream, CFileSize startPos,
#else
const Byte *inBuffer,
#endif
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
{
Byte *tempBuf[3] = { 0, 0, 0};
int i;
SZ_RESULT res = SzDecode2(packSizes, folder,
#ifdef _LZMA_IN_CB
inStream, startPos,
#else
inBuffer,
#endif
outBuffer, outSize, allocMain, tempBuf);
for (i = 0; i < 3; i++)
allocMain->Free(tempBuf[i]);
return res;
}

View File

@ -1,20 +0,0 @@
/* 7zDecode.h */
#ifndef __7Z_DECODE_H
#define __7Z_DECODE_H
#include "7zItem.h"
#include "7zAlloc.h"
#ifdef _LZMA_IN_CB
#include "7zIn.h"
#endif
SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
#ifdef _LZMA_IN_CB
ISzInStream *stream, CFileSize startPos,
#else
const Byte *inBuffer,
#endif
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
#endif

View File

@ -1,119 +0,0 @@
/* 7zExtract.c */
#include "7zExtract.h"
#include "7zDecode.h"
#include "../../7zCrc.h"
SZ_RESULT SzExtract(
ISzInStream *inStream,
CArchiveDatabaseEx *db,
UInt32 fileIndex,
UInt32 *blockIndex,
Byte **outBuffer,
size_t *outBufferSize,
size_t *offset,
size_t *outSizeProcessed,
ISzAlloc *allocMain,
ISzAlloc *allocTemp)
{
UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex];
SZ_RESULT res = SZ_OK;
*offset = 0;
*outSizeProcessed = 0;
if (folderIndex == (UInt32)-1)
{
allocMain->Free(*outBuffer);
*blockIndex = folderIndex;
*outBuffer = 0;
*outBufferSize = 0;
return SZ_OK;
}
if (*outBuffer == 0 || *blockIndex != folderIndex)
{
CFolder *folder = db->Database.Folders + folderIndex;
CFileSize unPackSizeSpec = SzFolderGetUnPackSize(folder);
size_t unPackSize = (size_t)unPackSizeSpec;
CFileSize startOffset = SzArDbGetFolderStreamPos(db, folderIndex, 0);
#ifndef _LZMA_IN_CB
Byte *inBuffer = 0;
size_t processedSize;
CFileSize packSizeSpec;
size_t packSize;
RINOK(SzArDbGetFolderFullPackSize(db, folderIndex, &packSizeSpec));
packSize = (size_t)packSizeSpec;
if (packSize != packSizeSpec)
return SZE_OUTOFMEMORY;
#endif
if (unPackSize != unPackSizeSpec)
return SZE_OUTOFMEMORY;
*blockIndex = folderIndex;
allocMain->Free(*outBuffer);
*outBuffer = 0;
RINOK(inStream->Seek(inStream, startOffset));
#ifndef _LZMA_IN_CB
if (packSize != 0)
{
inBuffer = (Byte *)allocTemp->Alloc(packSize);
if (inBuffer == 0)
return SZE_OUTOFMEMORY;
}
res = inStream->Read(inStream, inBuffer, packSize, &processedSize);
if (res == SZ_OK && processedSize != packSize)
res = SZE_FAIL;
#endif
if (res == SZ_OK)
{
*outBufferSize = unPackSize;
if (unPackSize != 0)
{
*outBuffer = (Byte *)allocMain->Alloc(unPackSize);
if (*outBuffer == 0)
res = SZE_OUTOFMEMORY;
}
if (res == SZ_OK)
{
res = SzDecode(db->Database.PackSizes +
db->FolderStartPackStreamIndex[folderIndex], folder,
#ifdef _LZMA_IN_CB
inStream, startOffset,
#else
inBuffer,
#endif
*outBuffer, unPackSize, allocTemp);
if (res == SZ_OK)
{
if (folder->UnPackCRCDefined)
{
if (CrcCalc(*outBuffer, unPackSize) != folder->UnPackCRC)
res = SZE_CRC_ERROR;
}
}
}
}
#ifndef _LZMA_IN_CB
allocTemp->Free(inBuffer);
#endif
}
if (res == SZ_OK)
{
UInt32 i;
CFileItem *fileItem = db->Database.Files + fileIndex;
*offset = 0;
for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
*offset += (UInt32)db->Database.Files[i].Size;
*outSizeProcessed = (size_t)fileItem->Size;
if (*offset + *outSizeProcessed > *outBufferSize)
return SZE_FAIL;
{
if (fileItem->IsFileCRCDefined)
{
if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)
res = SZE_CRC_ERROR;
}
}
}
return res;
}

View File

@ -1,40 +0,0 @@
/* 7zExtract.h */
#ifndef __7Z_EXTRACT_H
#define __7Z_EXTRACT_H
#include "7zIn.h"
/*
SzExtract extracts file from archive
*outBuffer must be 0 before first call for each new archive.
Extracting cache:
If you need to decompress more than one file, you can send
these values from previous call:
*blockIndex,
*outBuffer,
*outBufferSize
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed.
If you use external function, you can declare these 3 cache variables
(blockIndex, outBuffer, outBufferSize) as static in that external function.
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/
SZ_RESULT SzExtract(
ISzInStream *inStream,
CArchiveDatabaseEx *db,
UInt32 fileIndex, /* index of file */
UInt32 *blockIndex, /* index of solid block */
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
size_t *outBufferSize, /* buffer size for output buffer */
size_t *offset, /* offset of stream for required file in *outBuffer */
size_t *outSizeProcessed, /* size of file in *outBuffer */
ISzAlloc *allocMain,
ISzAlloc *allocTemp);
#endif

View File

@ -1,5 +0,0 @@
/* 7zHeader.c */
#include "7zHeader.h"
Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};

View File

@ -1,55 +0,0 @@
/* 7zHeader.h */
#ifndef __7Z_HEADER_H
#define __7Z_HEADER_H
#include "../../Types.h"
#define k7zSignatureSize 6
extern Byte k7zSignature[k7zSignatureSize];
#define k7zMajorVersion 0
#define k7zStartHeaderSize 0x20
enum EIdEnum
{
k7zIdEnd,
k7zIdHeader,
k7zIdArchiveProperties,
k7zIdAdditionalStreamsInfo,
k7zIdMainStreamsInfo,
k7zIdFilesInfo,
k7zIdPackInfo,
k7zIdUnPackInfo,
k7zIdSubStreamsInfo,
k7zIdSize,
k7zIdCRC,
k7zIdFolder,
k7zIdCodersUnPackSize,
k7zIdNumUnPackStream,
k7zIdEmptyStream,
k7zIdEmptyFile,
k7zIdAnti,
k7zIdName,
k7zIdCreationTime,
k7zIdLastAccessTime,
k7zIdLastWriteTime,
k7zIdWinAttributes,
k7zIdComment,
k7zIdEncodedHeader,
k7zIdStartPos
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,55 +0,0 @@
/* 7zIn.h */
#ifndef __7Z_IN_H
#define __7Z_IN_H
#include "7zHeader.h"
#include "7zItem.h"
#include "7zAlloc.h"
typedef struct _CInArchiveInfo
{
CFileSize StartPositionAfterHeader;
CFileSize DataStartPosition;
}CInArchiveInfo;
typedef struct _CArchiveDatabaseEx
{
CArchiveDatabase Database;
CInArchiveInfo ArchiveInfo;
UInt32 *FolderStartPackStreamIndex;
CFileSize *PackStreamStartPositions;
UInt32 *FolderStartFileIndex;
UInt32 *FileIndexToFolderIndexMap;
}CArchiveDatabaseEx;
void SzArDbExInit(CArchiveDatabaseEx *db);
void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *));
CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder);
int SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex, CFileSize *resSize);
typedef struct _ISzInStream
{
#ifdef _LZMA_IN_CB
SZ_RESULT (*Read)(
void *object, /* pointer to ISzInStream itself */
void **buffer, /* out: pointer to buffer with data */
size_t maxRequiredSize, /* max required size to read */
size_t *processedSize); /* real processed size.
processedSize can be less than maxRequiredSize.
If processedSize == 0, then there are no more
bytes in stream. */
#else
SZ_RESULT (*Read)(void *object, void *buffer, size_t size, size_t *processedSize);
#endif
SZ_RESULT (*Seek)(void *object, CFileSize pos);
} ISzInStream;
int SzArchiveOpen(
ISzInStream *inStream,
CArchiveDatabaseEx *db,
ISzAlloc *allocMain,
ISzAlloc *allocTemp);
#endif

View File

@ -1,134 +0,0 @@
/* 7zItem.c */
#include "7zItem.h"
#include "7zAlloc.h"
void SzCoderInfoInit(CCoderInfo *coder)
{
SzByteBufferInit(&coder->Properties);
}
void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p))
{
SzByteBufferFree(&coder->Properties, freeFunc);
SzCoderInfoInit(coder);
}
void SzFolderInit(CFolder *folder)
{
folder->NumCoders = 0;
folder->Coders = 0;
folder->NumBindPairs = 0;
folder->BindPairs = 0;
folder->NumPackStreams = 0;
folder->PackStreams = 0;
folder->UnPackSizes = 0;
folder->UnPackCRCDefined = 0;
folder->UnPackCRC = 0;
folder->NumUnPackStreams = 0;
}
void SzFolderFree(CFolder *folder, void (*freeFunc)(void *p))
{
UInt32 i;
for (i = 0; i < folder->NumCoders; i++)
SzCoderInfoFree(&folder->Coders[i], freeFunc);
freeFunc(folder->Coders);
freeFunc(folder->BindPairs);
freeFunc(folder->PackStreams);
freeFunc(folder->UnPackSizes);
SzFolderInit(folder);
}
UInt32 SzFolderGetNumOutStreams(CFolder *folder)
{
UInt32 result = 0;
UInt32 i;
for (i = 0; i < folder->NumCoders; i++)
result += folder->Coders[i].NumOutStreams;
return result;
}
int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex)
{
UInt32 i;
for(i = 0; i < folder->NumBindPairs; i++)
if (folder->BindPairs[i].InIndex == inStreamIndex)
return i;
return -1;
}
int SzFolderFindBindPairForOutStream(CFolder *folder, UInt32 outStreamIndex)
{
UInt32 i;
for(i = 0; i < folder->NumBindPairs; i++)
if (folder->BindPairs[i].OutIndex == outStreamIndex)
return i;
return -1;
}
CFileSize SzFolderGetUnPackSize(CFolder *folder)
{
int i = (int)SzFolderGetNumOutStreams(folder);
if (i == 0)
return 0;
for (i--; i >= 0; i--)
if (SzFolderFindBindPairForOutStream(folder, i) < 0)
return folder->UnPackSizes[i];
/* throw 1; */
return 0;
}
/*
int FindPackStreamArrayIndex(int inStreamIndex) const
{
for(int i = 0; i < PackStreams.Size(); i++)
if (PackStreams[i] == inStreamIndex)
return i;
return -1;
}
*/
void SzFileInit(CFileItem *fileItem)
{
fileItem->IsFileCRCDefined = 0;
fileItem->HasStream = 1;
fileItem->IsDirectory = 0;
fileItem->IsAnti = 0;
fileItem->IsLastWriteTimeDefined = 0;
fileItem->Name = 0;
}
void SzFileFree(CFileItem *fileItem, void (*freeFunc)(void *p))
{
freeFunc(fileItem->Name);
SzFileInit(fileItem);
}
void SzArchiveDatabaseInit(CArchiveDatabase *db)
{
db->NumPackStreams = 0;
db->PackSizes = 0;
db->PackCRCsDefined = 0;
db->PackCRCs = 0;
db->NumFolders = 0;
db->Folders = 0;
db->NumFiles = 0;
db->Files = 0;
}
void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *))
{
UInt32 i;
for (i = 0; i < db->NumFolders; i++)
SzFolderFree(&db->Folders[i], freeFunc);
for (i = 0; i < db->NumFiles; i++)
SzFileFree(&db->Files[i], freeFunc);
freeFunc(db->PackSizes);
freeFunc(db->PackCRCsDefined);
freeFunc(db->PackCRCs);
freeFunc(db->Folders);
freeFunc(db->Files);
SzArchiveDatabaseInit(db);
}

View File

@ -1,95 +0,0 @@
/* 7zItem.h */
#ifndef __7Z_ITEM_H
#define __7Z_ITEM_H
#include "7zMethodID.h"
#include "7zHeader.h"
#include "7zBuffer.h"
typedef struct _CCoderInfo
{
UInt32 NumInStreams;
UInt32 NumOutStreams;
CMethodID MethodID;
CSzByteBuffer Properties;
}CCoderInfo;
void SzCoderInfoInit(CCoderInfo *coder);
void SzCoderInfoFree(CCoderInfo *coder, void (*freeFunc)(void *p));
typedef struct _CBindPair
{
UInt32 InIndex;
UInt32 OutIndex;
}CBindPair;
typedef struct _CFolder
{
UInt32 NumCoders;
CCoderInfo *Coders;
UInt32 NumBindPairs;
CBindPair *BindPairs;
UInt32 NumPackStreams;
UInt32 *PackStreams;
CFileSize *UnPackSizes;
int UnPackCRCDefined;
UInt32 UnPackCRC;
UInt32 NumUnPackStreams;
}CFolder;
void SzFolderInit(CFolder *folder);
CFileSize SzFolderGetUnPackSize(CFolder *folder);
int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex);
UInt32 SzFolderGetNumOutStreams(CFolder *folder);
CFileSize SzFolderGetUnPackSize(CFolder *folder);
typedef struct _CArchiveFileTime
{
UInt32 Low;
UInt32 High;
} CArchiveFileTime;
typedef struct _CFileItem
{
CArchiveFileTime LastWriteTime;
/*
CFileSize StartPos;
UInt32 Attributes;
*/
CFileSize Size;
UInt32 FileCRC;
char *Name;
Byte IsFileCRCDefined;
Byte HasStream;
Byte IsDirectory;
Byte IsAnti;
Byte IsLastWriteTimeDefined;
/*
int AreAttributesDefined;
int IsLastWriteTimeDefined;
int IsStartPosDefined;
*/
}CFileItem;
void SzFileInit(CFileItem *fileItem);
typedef struct _CArchiveDatabase
{
UInt32 NumPackStreams;
CFileSize *PackSizes;
Byte *PackCRCsDefined;
UInt32 *PackCRCs;
UInt32 NumFolders;
CFolder *Folders;
UInt32 NumFiles;
CFileItem *Files;
}CArchiveDatabase;
void SzArchiveDatabaseInit(CArchiveDatabase *db);
void SzArchiveDatabaseFree(CArchiveDatabase *db, void (*freeFunc)(void *));
#endif

View File

@ -1,428 +0,0 @@
/*
7zMain.c
Test application for 7z Decoder
LZMA SDK 4.43 Copyright (c) 1999-2006 Igor Pavlov (2006-06-04)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#define USE_WINDOWS_FUNCTIONS
#endif
#ifdef USE_WINDOWS_FUNCTIONS
#include <windows.h>
#endif
#include "7zIn.h"
#include "7zExtract.h"
#include "../../7zCrc.h"
#ifdef USE_WINDOWS_FUNCTIONS
typedef HANDLE MY_FILE_HANDLE;
#else
typedef FILE *MY_FILE_HANDLE;
#endif
void ConvertNumberToString(CFileSize value, char *s)
{
char temp[32];
int pos = 0;
do
{
temp[pos++] = (char)('0' + (int)(value % 10));
value /= 10;
}
while (value != 0);
do
*s++ = temp[--pos];
while(pos > 0);
*s = '\0';
}
#define PERIOD_4 (4 * 365 + 1)
#define PERIOD_100 (PERIOD_4 * 25 - 1)
#define PERIOD_400 (PERIOD_100 * 4 + 1)
void ConvertFileTimeToString(CArchiveFileTime *ft, char *s)
{
unsigned year, mon, day, hour, min, sec;
UInt64 v64 = ft->Low | ((UInt64)ft->High << 32);
Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
unsigned temp;
UInt32 v;
v64 /= 10000000;
sec = (unsigned)(v64 % 60);
v64 /= 60;
min = (unsigned)(v64 % 60);
v64 /= 60;
hour = (unsigned)(v64 % 24);
v64 /= 24;
v = (UInt32)v64;
year = (unsigned)(1601 + v / PERIOD_400 * 400);
v %= PERIOD_400;
temp = (unsigned)(v / PERIOD_100);
if (temp == 4)
temp = 3;
year += temp * 100;
v -= temp * PERIOD_100;
temp = v / PERIOD_4;
if (temp == 25)
temp = 24;
year += temp * 4;
v -= temp * PERIOD_4;
temp = v / 365;
if (temp == 4)
temp = 3;
year += temp;
v -= temp * 365;
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
ms[1] = 29;
for (mon = 1; mon <= 12; mon++)
{
unsigned s = ms[mon - 1];
if (v < s)
break;
v -= s;
}
day = (unsigned)v + 1;
sprintf(s, "%04d-%02d-%02d %02d:%02d:%02d", year, mon, day, hour, min, sec);
}
#ifdef USE_WINDOWS_FUNCTIONS
/*
ReadFile and WriteFile functions in Windows have BUG:
If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
(Insufficient system resources exist to complete the requested service).
*/
#define kChunkSizeMax (1 << 24)
#endif
size_t MyReadFile(MY_FILE_HANDLE file, void *data, size_t size)
{
if (size == 0)
return 0;
#ifdef USE_WINDOWS_FUNCTIONS
{
size_t processedSize = 0;
do
{
DWORD curSize = (size > kChunkSizeMax) ? kChunkSizeMax : (DWORD)size;
DWORD processedLoc = 0;
BOOL res = ReadFile(file, data, curSize, &processedLoc, NULL);
data = (void *)((unsigned char *)data + processedLoc);
size -= processedLoc;
processedSize += processedLoc;
if (!res || processedLoc == 0)
break;
}
while (size > 0);
return processedSize;
}
#else
return fread(data, 1, size, file);
#endif
}
size_t MyWriteFile(MY_FILE_HANDLE file, void *data, size_t size)
{
if (size == 0)
return 0;
#ifdef USE_WINDOWS_FUNCTIONS
{
size_t processedSize = 0;
do
{
DWORD curSize = (size > kChunkSizeMax) ? kChunkSizeMax : (DWORD)size;
DWORD processedLoc = 0;
BOOL res = WriteFile(file, data, curSize, &processedLoc, NULL);
data = (void *)((unsigned char *)data + processedLoc);
size -= processedLoc;
processedSize += processedLoc;
if (!res)
break;
}
while (size > 0);
return processedSize;
}
#else
return fwrite(data, 1, size, file);
#endif
}
int MyCloseFile(MY_FILE_HANDLE file)
{
#ifdef USE_WINDOWS_FUNCTIONS
return (CloseHandle(file) != FALSE) ? 0 : 1;
#else
return fclose(file);
#endif
}
typedef struct _CFileInStream
{
ISzInStream InStream;
MY_FILE_HANDLE File;
} CFileInStream;
#ifdef _LZMA_IN_CB
#define kBufferSize (1 << 12)
Byte g_Buffer[kBufferSize];
SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize)
{
CFileInStream *s = (CFileInStream *)object;
size_t processedSizeLoc;
if (maxRequiredSize > kBufferSize)
maxRequiredSize = kBufferSize;
processedSizeLoc = MyReadFile(s->File, g_Buffer, maxRequiredSize);
*buffer = g_Buffer;
if (processedSize != 0)
*processedSize = processedSizeLoc;
return SZ_OK;
}
#else
SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize)
{
CFileInStream *s = (CFileInStream *)object;
size_t processedSizeLoc = MyReadFile(s->File, buffer, size);
if (processedSize != 0)
*processedSize = processedSizeLoc;
return SZ_OK;
}
#endif
SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
{
CFileInStream *s = (CFileInStream *)object;
#ifdef USE_WINDOWS_FUNCTIONS
{
LARGE_INTEGER value;
value.LowPart = (DWORD)pos;
value.HighPart = (LONG)((UInt64)pos >> 32);
#ifdef _SZ_FILE_SIZE_32
/* VC 6.0 has bug with >> 32 shifts. */
value.HighPart = 0;
#endif
value.LowPart = SetFilePointer(s->File, value.LowPart, &value.HighPart, FILE_BEGIN);
if (value.LowPart == 0xFFFFFFFF)
if(GetLastError() != NO_ERROR)
return SZE_FAIL;
return SZ_OK;
}
#else
int res = fseek(s->File, (long)pos, SEEK_SET);
if (res == 0)
return SZ_OK;
return SZE_FAIL;
#endif
}
void PrintError(char *sz)
{
printf("\nERROR: %s\n", sz);
}
int main(int numargs, char *args[])
{
CFileInStream archiveStream;
CArchiveDatabaseEx db;
SZ_RESULT res;
ISzAlloc allocImp;
ISzAlloc allocTempImp;
printf("\n7z ANSI-C Decoder 4.48 Copyright (c) 1999-2007 Igor Pavlov 2007-06-21\n");
if (numargs == 1)
{
printf(
"\nUsage: 7zDec <command> <archive_name>\n\n"
"<Commands>\n"
" e: Extract files from archive\n"
" l: List contents of archive\n"
" t: Test integrity of archive\n");
return 0;
}
if (numargs < 3)
{
PrintError("incorrect command");
return 1;
}
archiveStream.File =
#ifdef USE_WINDOWS_FUNCTIONS
CreateFile(args[2], GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (archiveStream.File == INVALID_HANDLE_VALUE)
#else
archiveStream.File = fopen(args[2], "rb");
if (archiveStream.File == 0)
#endif
{
PrintError("can not open input file");
return 1;
}
archiveStream.InStream.Read = SzFileReadImp;
archiveStream.InStream.Seek = SzFileSeekImp;
allocImp.Alloc = SzAlloc;
allocImp.Free = SzFree;
allocTempImp.Alloc = SzAllocTemp;
allocTempImp.Free = SzFreeTemp;
CrcGenerateTable();
SzArDbExInit(&db);
res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp);
if (res == SZ_OK)
{
char *command = args[1];
int listCommand = 0;
int testCommand = 0;
int extractCommand = 0;
if (strcmp(command, "l") == 0)
listCommand = 1;
if (strcmp(command, "t") == 0)
testCommand = 1;
else if (strcmp(command, "e") == 0)
extractCommand = 1;
if (listCommand)
{
UInt32 i;
for (i = 0; i < db.Database.NumFiles; i++)
{
CFileItem *f = db.Database.Files + i;
char s[32], t[32];
ConvertNumberToString(f->Size, s);
if (f->IsLastWriteTimeDefined)
ConvertFileTimeToString(&f->LastWriteTime, t);
else
strcpy(t, " ");
printf("%10s %s %s\n", s, t, f->Name);
}
}
else if (testCommand || extractCommand)
{
UInt32 i;
/*
if you need cache, use these 3 variables.
if you use external function, you can make these variable as static.
*/
UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
Byte *outBuffer = 0; /* it must be 0 before first call for each new archive. */
size_t outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
printf("\n");
for (i = 0; i < db.Database.NumFiles; i++)
{
size_t offset;
size_t outSizeProcessed;
CFileItem *f = db.Database.Files + i;
if (f->IsDirectory)
printf("Directory ");
else
printf(testCommand ?
"Testing ":
"Extracting");
printf(" %s", f->Name);
if (f->IsDirectory)
{
printf("\n");
continue;
}
res = SzExtract(&archiveStream.InStream, &db, i,
&blockIndex, &outBuffer, &outBufferSize,
&offset, &outSizeProcessed,
&allocImp, &allocTempImp);
if (res != SZ_OK)
break;
if (!testCommand)
{
MY_FILE_HANDLE outputHandle;
size_t processedSize;
char *fileName = f->Name;
size_t nameLen = strlen(f->Name);
for (; nameLen > 0; nameLen--)
if (f->Name[nameLen - 1] == '/')
{
fileName = f->Name + nameLen;
break;
}
outputHandle =
#ifdef USE_WINDOWS_FUNCTIONS
CreateFile(fileName, GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (outputHandle == INVALID_HANDLE_VALUE)
#else
fopen(fileName, "wb+");
if (outputHandle == 0)
#endif
{
PrintError("can not open output file");
res = SZE_FAIL;
break;
}
processedSize = MyWriteFile(outputHandle, outBuffer + offset, outSizeProcessed);
if (processedSize != outSizeProcessed)
{
PrintError("can not write output file");
res = SZE_FAIL;
break;
}
if (MyCloseFile(outputHandle))
{
PrintError("can not close output file");
res = SZE_FAIL;
break;
}
}
printf("\n");
}
allocImp.Free(outBuffer);
}
else
{
PrintError("incorrect command");
res = SZE_FAIL;
}
}
SzArDbExFree(&db, allocImp.Free);
MyCloseFile(archiveStream.File);
if (res == SZ_OK)
{
printf("\nEverything is Ok\n");
return 0;
}
if (res == (SZ_RESULT)SZE_NOTIMPL)
PrintError("decoder doesn't support this archive");
else if (res == (SZ_RESULT)SZE_OUTOFMEMORY)
PrintError("can not allocate memory");
else if (res == (SZ_RESULT)SZE_CRC_ERROR)
PrintError("CRC error");
else
printf("\nERROR #%d\n", res);
return 1;
}

View File

@ -1,10 +0,0 @@
/* 7zMethodID.c */
#include "7zMethodID.h"
/*
int AreMethodsEqual(CMethodID *a1, CMethodID *a2)
{
return (*a1 == *a2) ? 1 : 0;
}
*/

View File

@ -1,10 +0,0 @@
/* 7zMethodID.h */
#ifndef __7Z_METHOD_ID_H
#define __7Z_METHOD_ID_H
#include "../../Types.h"
typedef UInt64 CMethodID;
#endif

View File

@ -1,211 +0,0 @@
# Microsoft Developer Studio Project File - Name="7z_C" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=7z_C - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "7z_C.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "7z_C.mak" CFG="7z_C - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "7z_C - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "7z_C - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "7z_C - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W4 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/7zDec.exe" /opt:NOWIN98
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "7z_C - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W4 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /GZ /c
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/7zDec.exe" /pdbtype:sept
!ENDIF
# Begin Target
# Name "7z_C - Win32 Release"
# Name "7z_C - Win32 Debug"
# Begin Group "LZMA"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Compress\Lzma\LzmaDecode.c
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Lzma\LzmaDecode.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Lzma\LzmaTypes.h
# End Source File
# End Group
# Begin Group "Common"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\7zCrc.c
# End Source File
# Begin Source File
SOURCE=..\..\7zCrc.h
# End Source File
# Begin Source File
SOURCE=..\..\Types.h
# End Source File
# End Group
# Begin Group "Branch"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Compress\Branch\BranchTypes.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Branch\BranchX86.c
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Branch\BranchX86.h
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Branch\BranchX86_2.c
# End Source File
# Begin Source File
SOURCE=..\..\Compress\Branch\BranchX86_2.h
# End Source File
# End Group
# Begin Source File
SOURCE=.\7zAlloc.c
# End Source File
# Begin Source File
SOURCE=.\7zAlloc.h
# End Source File
# Begin Source File
SOURCE=.\7zBuffer.c
# End Source File
# Begin Source File
SOURCE=.\7zBuffer.h
# End Source File
# Begin Source File
SOURCE=.\7zDecode.c
# End Source File
# Begin Source File
SOURCE=.\7zDecode.h
# End Source File
# Begin Source File
SOURCE=.\7zExtract.c
# End Source File
# Begin Source File
SOURCE=.\7zExtract.h
# End Source File
# Begin Source File
SOURCE=.\7zHeader.c
# End Source File
# Begin Source File
SOURCE=.\7zHeader.h
# End Source File
# Begin Source File
SOURCE=.\7zIn.c
# End Source File
# Begin Source File
SOURCE=.\7zIn.h
# End Source File
# Begin Source File
SOURCE=.\7zItem.c
# End Source File
# Begin Source File
SOURCE=.\7zItem.h
# End Source File
# Begin Source File
SOURCE=.\7zMain.c
# End Source File
# Begin Source File
SOURCE=.\7zMethodID.c
# End Source File
# Begin Source File
SOURCE=.\7zMethodID.h
# End Source File
# End Target
# End Project

View File

@ -1,29 +0,0 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "7z_C"=.\7z_C.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@ -1,74 +0,0 @@
PROG = 7zDec.exe
!IFDEF CPU
LIBS = $(LIBS) bufferoverflowU.lib
CFLAGS = $(CFLAGS) -GS- -Zc:forScope -WX -GS- -Gy -W4
!ENDIF
!IFNDEF O
!IFDEF CPU
O=$(CPU)
!ELSE
O=O
!ENDIF
!ENDIF
CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -D_LZMA_IN_CB
CFLAGS_O1 = $(CFLAGS) -O1
CFLAGS_O2 = $(CFLAGS) -O2
LFLAGS = $(LFLAGS) -nologo -OPT:NOWIN98 -OPT:REF
PROGPATH = $O\$(PROG)
COMPL_O1 = $(CPP) $(CFLAGS_O1) $**
COMPL_O2 = $(CPP) $(CFLAGS_O2) $**
COMPL = $(CPP) $(CFLAGS_O1) $**
C_OBJS = \
$O\7zCrc.obj \
7Z_OBJS = \
$O\7zAlloc.obj \
$O\7zBuffer.obj \
$O\7zDecode.obj \
$O\7zExtract.obj \
$O\7zHeader.obj \
$O\7zIn.obj \
$O\7zItem.obj \
$O\7zMain.obj \
$O\7zMethodID.obj \
OBJS = \
$(7Z_OBJS) \
$O\LzmaDecode.obj \
$O\BranchX86.obj \
$O\BranchX86_2.obj \
$(C_OBJS) \
all: $(PROGPATH)
clean:
-del /Q $(PROGPATH) $O\*.exe $O\*.dll $O\*.obj $O\*.lib $O\*.exp $O\*.res $O\*.pch
$O:
if not exist "$O" mkdir "$O"
$(PROGPATH): $O $(OBJS)
link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS)
$(7Z_OBJS): $(*B).c
$(COMPL)
$O\LzmaDecode.obj: ../../Compress/Lzma/$(*B).c
$(COMPL_O2)
$O\BranchX86.obj: ../../Compress/Branch/$(*B).c
$(COMPL_O2)
$O\BranchX86_2.obj: ../../Compress/Branch/$(*B).c
$(COMPL_O2)
$(C_OBJS): ../../$(*B).c
$(COMPL_O2)

View File

@ -1,55 +0,0 @@
PROG = 7zDec
CXX = g++
LIB =
RM = rm -f
CFLAGS = -c -O2 -Wall -D_LZMA_IN_CB
OBJS = 7zAlloc.o 7zBuffer.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o 7zMethodID.o LzmaDecode.o BranchX86.o BranchX86_2.o
all: $(PROG)
$(PROG): $(OBJS)
$(CXX) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIB)
7zAlloc.o: 7zAlloc.c
$(CXX) $(CFLAGS) 7zAlloc.c
7zBuffer.o: 7zBuffer.c
$(CXX) $(CFLAGS) 7zBuffer.c
7zCrc.o: ../../7zCrc.c
$(CXX) $(CFLAGS) ../../7zCrc.c
7zDecode.o: 7zDecode.c
$(CXX) $(CFLAGS) 7zDecode.c
7zExtract.o: 7zExtract.c
$(CXX) $(CFLAGS) 7zExtract.c
7zHeader.o: 7zHeader.c
$(CXX) $(CFLAGS) 7zHeader.c
7zIn.o: 7zIn.c
$(CXX) $(CFLAGS) 7zIn.c
7zItem.o: 7zItem.c
$(CXX) $(CFLAGS) 7zItem.c
7zMain.o: 7zMain.c
$(CXX) $(CFLAGS) 7zMain.c
7zMethodID.o: 7zMethodID.c
$(CXX) $(CFLAGS) 7zMethodID.c
LzmaDecode.o: ../../Compress/Lzma/LzmaDecode.c
$(CXX) $(CFLAGS) ../../Compress/Lzma/LzmaDecode.c
BranchX86.o: ../../Compress/Branch/BranchX86.c
$(CXX) $(CFLAGS) ../../Compress/Branch/BranchX86.c
BranchX86_2.o: ../../Compress/Branch/BranchX86_2.c
$(CXX) $(CFLAGS) ../../Compress/Branch/BranchX86_2.c
clean:
-$(RM) $(PROG) $(OBJS)

View File

@ -1,26 +0,0 @@
/* BranchARM.c */
#include "BranchARM.h"
UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
{
UInt32 i;
for (i = 0; i + 4 <= size; i += 4)
{
if (data[i + 3] == 0xEB)
{
UInt32 dest;
UInt32 src = (data[i + 2] << 16) | (data[i + 1] << 8) | (data[i + 0]);
src <<= 2;
if (encoding)
dest = nowPos + i + 8 + src;
else
dest = src - (nowPos + i + 8);
dest >>= 2;
data[i + 2] = (Byte)(dest >> 16);
data[i + 1] = (Byte)(dest >> 8);
data[i + 0] = (Byte)dest;
}
}
return i;
}

View File

@ -1,10 +0,0 @@
/* BranchARM.h */
#ifndef __BRANCH_ARM_H
#define __BRANCH_ARM_H
#include "BranchTypes.h"
UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
#endif

View File

@ -1,35 +0,0 @@
/* BranchARMThumb.c */
#include "BranchARMThumb.h"
UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
{
UInt32 i;
for (i = 0; i + 4 <= size; i += 2)
{
if ((data[i + 1] & 0xF8) == 0xF0 &&
(data[i + 3] & 0xF8) == 0xF8)
{
UInt32 dest;
UInt32 src =
((data[i + 1] & 0x7) << 19) |
(data[i + 0] << 11) |
((data[i + 3] & 0x7) << 8) |
(data[i + 2]);
src <<= 1;
if (encoding)
dest = nowPos + i + 4 + src;
else
dest = src - (nowPos + i + 4);
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;
}

View File

@ -1,10 +0,0 @@
/* BranchARMThumb.h */
#ifndef __BRANCH_ARM_THUMB_H
#define __BRANCH_ARM_THUMB_H
#include "BranchTypes.h"
UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
#endif

View File

@ -1,66 +0,0 @@
/* BranchIA64.c */
#include "BranchIA64.h"
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
};
UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
{
UInt32 i;
for (i = 0; i + 16 <= 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
/* && (instNorm & 0x3F)== 0 */
)
{
UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF);
UInt32 dest;
src |= ((UInt32)(instNorm >> 36) & 1) << 20;
src <<= 4;
if (encoding)
dest = nowPos + i + src;
else
dest = src - (nowPos + 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;
}

View File

@ -1,10 +0,0 @@
/* BranchIA64.h */
#ifndef __BRANCH_IA64_H
#define __BRANCH_IA64_H
#include "BranchTypes.h"
UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
#endif

View File

@ -1,36 +0,0 @@
/* BranchPPC.c */
#include "BranchPPC.h"
UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
{
UInt32 i;
for (i = 0; i + 4 <= size; i += 4)
{
/* PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link) */
if ((data[i] >> 2) == 0x12 &&
(
(data[i + 3] & 3) == 1
/* || (data[i+3] & 3) == 3 */
)
)
{
UInt32 src = ((data[i + 0] & 3) << 24) |
(data[i + 1] << 16) |
(data[i + 2] << 8) |
(data[i + 3] & (~3));
UInt32 dest;
if (encoding)
dest = nowPos + i + src;
else
dest = src - (nowPos + 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;
}

View File

@ -1,10 +0,0 @@
/* BranchPPC.h */
#ifndef __BRANCH_PPC_H
#define __BRANCH_PPC_H
#include "BranchTypes.h"
UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
#endif

View File

@ -1,36 +0,0 @@
/* BranchSPARC.c */
#include "BranchSPARC.h"
UInt32 SPARC_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
{
UInt32 i;
for (i = 0; i + 4 <= 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 = nowPos + i + src;
else
dest = src - (nowPos + 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;
}

View File

@ -1,10 +0,0 @@
/* BranchSPARC.h */
#ifndef __BRANCH_SPARC_H
#define __BRANCH_SPARC_H
#include "BranchTypes.h"
UInt32 SPARC_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
#endif

View File

@ -1,51 +0,0 @@
/* BranchTypes.h */
#ifndef __BRANCHTYPES_H
#define __BRANCHTYPES_H
#ifndef _7ZIP_BYTE_DEFINED
#define _7ZIP_BYTE_DEFINED
typedef unsigned char Byte;
#endif
#ifndef _7ZIP_UINT16_DEFINED
#define _7ZIP_UINT16_DEFINED
typedef unsigned short UInt16;
#endif
#ifndef _7ZIP_UINT32_DEFINED
#define _7ZIP_UINT32_DEFINED
#ifdef _LZMA_UINT32_IS_ULONG
typedef unsigned long UInt32;
#else
typedef unsigned int UInt32;
#endif
#endif
#ifndef _7ZIP_UINT64_DEFINED
#define _7ZIP_UINT64_DEFINED
#ifdef _SZ_NO_INT_64
typedef unsigned long UInt64;
#else
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 UInt64;
#else
typedef unsigned long long int UInt64;
#endif
#endif
#endif
/* #define _LZMA_NO_SYSTEM_SIZE_T */
/* You can use it, if you don't want <stddef.h> */
#ifndef _7ZIP_SIZET_DEFINED
#define _7ZIP_SIZET_DEFINED
#ifdef _LZMA_NO_SYSTEM_SIZE_T
typedef UInt32 SizeT;
#else
#include <stddef.h>
typedef size_t SizeT;
#endif
#endif
#endif

View File

@ -1,84 +0,0 @@
/* BranchX86.c */
#include "BranchX86.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 *buffer, SizeT endPos, UInt32 nowPos, UInt32 *prevMaskMix, int encoding)
{
SizeT bufferPos = 0, prevPosT;
UInt32 prevMask = *prevMaskMix & 0x7;
if (endPos < 5)
return 0;
nowPos += 5;
prevPosT = (SizeT)0 - 1;
for(;;)
{
Byte *p = buffer + bufferPos;
Byte *limit = buffer + endPos - 4;
for (; p < limit; p++)
if ((*p & 0xFE) == 0xE8)
break;
bufferPos = (SizeT)(p - buffer);
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 = (nowPos + (UInt32)bufferPos) + src;
else
dest = src - (nowPos + (UInt32)bufferPos);
if (prevMask == 0)
break;
index = kMaskToBitNumber[prevMask] * 8;
b = (Byte)(dest >> (24 - index));
if (!Test86MSByte(b))
break;
src = dest ^ ((1 << (32 - index)) - 1);
}
p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
p[3] = (Byte)(dest >> 16);
p[2] = (Byte)(dest >> 8);
p[1] = (Byte)dest;
bufferPos += 5;
}
else
{
prevMask = ((prevMask << 1) & 0x7) | 1;
bufferPos++;
}
}
prevPosT = bufferPos - prevPosT;
*prevMaskMix = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
return bufferPos;
}

View File

@ -1,12 +0,0 @@
/* BranchX86.h */
#ifndef __BRANCHX86_H
#define __BRANCHX86_H
#include "BranchTypes.h"
#define x86_Convert_Init(state) { state = 0; }
SizeT x86_Convert(Byte *buffer, SizeT endPos, UInt32 nowPos, UInt32 *state, int encoding);
#endif

View File

@ -1,135 +0,0 @@
// BranchX86_2.c
#include "BranchX86_2.h"
#include "../../Alloc.h"
#ifdef _LZMA_PROB32
#define CProb UInt32
#else
#define CProb UInt16
#endif
#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kNumMoveBits 5
#define RC_READ_BYTE (*Buffer++)
#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
{ int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
#define RC_TEST { if (Buffer == BufferLim) return BCJ2_RESULT_DATA_ERROR; }
#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
// #define UpdateBit0(p) Range = bound; *(p) = (CProb)(*(p) + ((kBitModelTotal - *(p)) >> kNumMoveBits));
// #define UpdateBit1(p) Range -= bound; Code -= bound; *(p) = (CProb)(*(p) - (*(p) >> kNumMoveBits));
int x86_2_Decode(
const Byte *buf0, SizeT size0,
const Byte *buf1, SizeT size1,
const Byte *buf2, SizeT size2,
const Byte *buf3, SizeT size3,
Byte *outBuf, SizeT outSize)
{
CProb p[256 + 2];
SizeT inPos = 0, outPos = 0;
const Byte *Buffer, *BufferLim;
UInt32 Range, Code;
Byte prevByte = 0;
unsigned int i;
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
p[i] = kBitModelTotal >> 1;
RC_INIT(buf3, size3);
if (outSize == 0)
return BCJ2_RESULT_OK;
for (;;)
{
Byte b;
CProb *prob;
UInt32 bound;
SizeT limit = size0 - inPos;
if (outSize - outPos < limit)
limit = outSize - outPos;
while (limit != 0)
{
Byte b = buf0[inPos];
outBuf[outPos++] = b;
if (IsJ(prevByte, b))
break;
inPos++;
prevByte = b;
limit--;
}
if (limit == 0 || outPos == outSize)
break;
b = buf0[inPos++];
if (b == 0xE8)
prob = p + prevByte;
else if (b == 0xE9)
prob = p + 256;
else
prob = p + 257;
IfBit0(prob)
{
UpdateBit0(prob)
prevByte = b;
}
else
{
UInt32 dest;
const Byte *v;
UpdateBit1(prob)
if (b == 0xE8)
{
v = buf1;
if (size1 < 4)
return BCJ2_RESULT_DATA_ERROR;
buf1 += 4;
size1 -= 4;
}
else
{
v = buf2;
if (size2 < 4)
return BCJ2_RESULT_DATA_ERROR;
buf2 += 4;
size2 -= 4;
}
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
outBuf[outPos++] = (Byte)dest;
if (outPos == outSize)
break;
outBuf[outPos++] = (Byte)(dest >> 8);
if (outPos == outSize)
break;
outBuf[outPos++] = (Byte)(dest >> 16);
if (outPos == outSize)
break;
outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
}
}
return (outPos == outSize) ? BCJ2_RESULT_OK : BCJ2_RESULT_DATA_ERROR;
}

View File

@ -1,28 +0,0 @@
// BranchX86_2.h
#ifndef __BRANCHX86_2_H
#define __BRANCHX86_2_H
#include "BranchTypes.h"
#define BCJ2_RESULT_OK 0
#define BCJ2_RESULT_DATA_ERROR 1
/*
Conditions:
outSize <= FullOutputSize,
where FullOutputSize is full size of output stream of x86_2 filter.
If buf0 overlaps outBuf, there are two required conditions:
1) (buf0 >= outBuf)
2) (buf0 + size0 >= outBuf + FullOutputSize).
*/
int x86_2_Decode(
const Byte *buf0, SizeT size0,
const Byte *buf1, SizeT size1,
const Byte *buf2, SizeT size2,
const Byte *buf3, SizeT size3,
Byte *outBuf, SizeT outSize);
#endif

View File

@ -1,146 +0,0 @@
/* Compress/HuffmanEncode.c */
#include "HuffmanEncode.h"
#include "../../Sort.h"
#define kMaxLen 16
#define NUM_BITS 10
#define MASK ((1 << NUM_BITS) - 1)
#define NUM_COUNTERS 64
/* use BLOCK_SORT_EXTERNAL_FLAGS if blockSize > 1M */
#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 = 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]]++;
}
}
}
}
}

View File

@ -1,18 +0,0 @@
/* Compress/HuffmanEncode.h */
#ifndef __COMPRESS_HUFFMANENCODE_H
#define __COMPRESS_HUFFMANENCODE_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

View File

@ -1,53 +0,0 @@
/* LzHash.h */
#ifndef __C_LZHASH_H
#define __C_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 = g_CrcTable[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
#define HASH4_CALC { \
UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (g_CrcTable[cur[3]] << 5)) & p->hashMask; }
#define HASH5_CALC { \
UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (g_CrcTable[cur[3]] << 5)); \
hashValue = (hash4Value ^ (g_CrcTable[cur[4]] << 3)) & p->hashMask; \
hash4Value &= (kHash4Size - 1); }
/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ g_CrcTable[cur[2]]) & 0xFFFF; */
#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ g_CrcTable[cur[1]]) & 0xFFFF;
#define MT_HASH2_CALC \
hash2Value = (g_CrcTable[cur[0]] ^ cur[1]) & (kHash2Size - 1);
#define MT_HASH3_CALC { \
UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
#define MT_HASH4_CALC { \
UInt32 temp = g_CrcTable[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (g_CrcTable[cur[3]] << 5)) & (kHash4Size - 1); }
#endif

View File

@ -1,742 +0,0 @@
/* MatchFinder.c */
/* Please call InitCrcTable before */
#include <string.h>
#include "MatchFinder.h"
#include "LzHash.h"
#include "../../7zCrc.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
void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
{
if (!p->directInput)
{
alloc->Free(p->bufferBase);
p->bufferBase = 0;
}
}
/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
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(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;
}
void MatchFinder_ReadBlock(CMatchFinder *p)
{
if (p->streamEndWasReached || p->result != SZ_OK)
return;
for (;;)
{
Byte *dest = p->buffer + (p->streamPos - p->pos);
UInt32 numReadBytes;
UInt32 size = (UInt32)(p->bufferBase + p->blockSize - dest);
if (size == 0)
return;
p->result = p->stream->Read(p->stream, dest, size, &numReadBytes);
if (p->result != SZ_OK)
return;
if (numReadBytes == 0)
{
p->streamEndWasReached = 1;
return;
}
p->streamPos += numReadBytes;
if (p->streamPos - p->pos > p->keepSizeAfter)
return;
}
}
void MatchFinder_MoveBlock(CMatchFinder *p)
{
memmove(p->bufferBase,
p->buffer - p->keepSizeBefore,
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);
}
void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
{
if (MatchFinder_NeedMove(p))
MatchFinder_MoveBlock(p);
MatchFinder_ReadBlock(p);
}
void MatchFinder_SetDefaultSettings(CMatchFinder *p)
{
p->cutValue = 32;
p->btMode = 1;
p->numHashBytes = 4;
/* p->skipModeBits = 0; */
p->directInput = 0;
p->bigHash = 0;
}
void MatchFinder_Construct(CMatchFinder *p)
{
p->bufferBase = 0;
p->directInput = 0;
p->hash = 0;
MatchFinder_SetDefaultSettings(p);
}
void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
{
alloc->Free(p->hash);
p->hash = 0;
}
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
{
MatchFinder_FreeThisClassMemory(p, alloc);
LzInWindow_Free(p, alloc);
}
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(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;
}
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);
}
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;
}
}
void MatchFinder_Normalize(CMatchFinder *p)
{
UInt32 subValue = MatchFinder_GetSubValue(p);
MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
MatchFinder_ReduceOffsets(p, subValue);
}
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);
}
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;
}
}
}
}
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;
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;
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)
}
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)
}
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)
}
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
}
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);
}
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);
}
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);
}
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;
}
}

View File

@ -1,106 +0,0 @@
/* MatchFinder.h */
#ifndef __MATCHFINDER_H
#define __MATCHFINDER_H
#include "../../IStream.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;
HRes result;
} 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

View File

@ -1,806 +0,0 @@
/* MatchFinderMt.c */
#ifdef _WIN32
#define USE_ALLOCA
#endif
#ifdef USE_ALLOCA
#ifdef _WIN32
#include <malloc.h>
#else
#include <stdlib.h>
#endif
#endif
#include "../../7zCrc.h"
#include "LzHash.h"
#include "MatchFinderMt.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;
}
HRes MtSync_Create2(CMtSync *p, unsigned (StdCall *startAddress)(void *), void *obj, UInt32 numBlocks)
{
if (p->wasCreated)
return SZ_OK;
RINOK(CriticalSection_Init(&p->cs));
p->csWasInitialized = True;
RINOK(AutoResetEvent_CreateNotSignaled(&p->canStart));
RINOK(AutoResetEvent_CreateNotSignaled(&p->wasStarted));
RINOK(AutoResetEvent_CreateNotSignaled(&p->wasStopped));
RINOK(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks));
RINOK(Semaphore_Create(&p->filledSemaphore, 0, numBlocks));
p->needStart = True;
RINOK(Thread_Create(&p->thread, startAddress, obj));
p->wasCreated = True;
return SZ_OK;
}
HRes MtSync_Create(CMtSync *p, unsigned (StdCall *startAddress)(void *), void *obj, UInt32 numBlocks)
{
HRes 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_GetHeads(name, v) \
static void GetHeads ## name(const Byte *p, UInt32 pos, \
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads) { \
for (; numHeads != 0; numHeads--) { \
const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
DEF_GetHeads(2, (p[0] | ((UInt32)p[1] << 8)) & hashMask)
DEF_GetHeads(3, (g_CrcTable[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
DEF_GetHeads(4, (g_CrcTable[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (g_CrcTable[p[3]] << 5)) & hashMask)
DEF_GetHeads(4b, (g_CrcTable[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)
DEF_GetHeads(5, (g_CrcTable[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (g_CrcTable[p[3]] << 5) ^ (g_CrcTable[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);
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
#if _MSC_VER >= 1300
#define NO_INLINE __declspec(noinline) __fastcall
#else
#ifdef _MSC_VER
#define NO_INLINE __fastcall
#endif
#endif
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(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 StdCall HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
static unsigned StdCall BtThreadFunc2(void *p)
{
#ifdef USE_ALLOCA
alloca(0x180);
#endif
BtThreadFunc((CMatchFinderMt *)p);
return 0;
}
HRes 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 E_INVALIDARG;
if (p->hashBuf == 0)
{
p->hashBuf = (UInt32 *)alloc->Alloc((kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
if (p->hashBuf == 0)
return SZE_OUTOFMEMORY;
p->btBuf = p->hashBuf + kHashBufferSize;
}
keepAddBufferBefore += (kHashBufferSize + kBtBufferSize);
keepAddBufferAfter += kMtHashBlockSize;
if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc))
return SZE_OUTOFMEMORY;
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->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;
*/
}
}

View File

@ -1,95 +0,0 @@
/* MatchFinderMt.h */
#ifndef __MATCHFINDERMT_H
#define __MATCHFINDERMT_H
#include "../../Threads.h"
#include "MatchFinder.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);
typedef struct _CMatchFinderMt
{
/* LZ */
const Byte *pointerToCurPos;
UInt32 *btBuf;
UInt32 btBufPos;
UInt32 btBufPosLimit;
UInt32 lzPos;
UInt32 btNumAvailBytes;
UInt32 *hash;
UInt32 fixedHashSize;
UInt32 historySize;
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);
HRes 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

View File

@ -1,584 +0,0 @@
/*
LzmaDecode.c
LZMA Decoder (optimized for Speed version)
LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this Code, expressly permits you to
statically or dynamically link your Code (or bind by name) to the
interfaces of this file without subjecting your linked Code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#include "LzmaDecode.h"
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kNumMoveBits 5
#define RC_READ_BYTE (*Buffer++)
#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
{ int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
#ifdef _LZMA_IN_CB
#define RC_TEST { if (Buffer == BufferLim) \
{ SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \
BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }}
#define RC_INIT Buffer = BufferLim = 0; RC_INIT2
#else
#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; }
#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
#endif
#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
{ UpdateBit0(p); mi <<= 1; A0; } else \
{ UpdateBit1(p); mi = (mi + mi) + 1; A1; }
#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
{ int i = numLevels; res = 1; \
do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
res -= (1 << numLevels); }
#define kNumPosBitsMax 4
#define kNumPosStatesMax (1 << kNumPosBitsMax)
#define kLenNumLowBits 3
#define kLenNumLowSymbols (1 << kLenNumLowBits)
#define kLenNumMidBits 3
#define kLenNumMidSymbols (1 << kLenNumMidBits)
#define kLenNumHighBits 8
#define kLenNumHighSymbols (1 << kLenNumHighBits)
#define LenChoice 0
#define LenChoice2 (LenChoice + 1)
#define LenLow (LenChoice2 + 1)
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
#define kNumStates 12
#define kNumLitStates 7
#define kStartPosModelIndex 4
#define kEndPosModelIndex 14
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
#define kNumPosSlotBits 6
#define kNumLenToPosStates 4
#define kNumAlignBits 4
#define kAlignTableSize (1 << kNumAlignBits)
#define kMatchMinLen 2
#define IsMatch 0
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
#define IsRepG0 (IsRep + kNumStates)
#define IsRepG1 (IsRepG0 + kNumStates)
#define IsRepG2 (IsRepG1 + kNumStates)
#define IsRep0Long (IsRepG2 + kNumStates)
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
#define LenCoder (Align + kAlignTableSize)
#define RepLenCoder (LenCoder + kNumLenProbs)
#define Literal (RepLenCoder + kNumLenProbs)
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
{
unsigned char prop0;
if (size < LZMA_PROPERTIES_SIZE)
return LZMA_RESULT_DATA_ERROR;
prop0 = propsData[0];
if (prop0 >= (9 * 5 * 5))
return LZMA_RESULT_DATA_ERROR;
{
for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
propsRes->lc = prop0;
/*
unsigned char remainder = (unsigned char)(prop0 / 9);
propsRes->lc = prop0 % 9;
propsRes->pb = remainder / 5;
propsRes->lp = remainder % 5;
*/
}
#ifdef _LZMA_OUT_READ
{
int i;
propsRes->DictionarySize = 0;
for (i = 0; i < 4; i++)
propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
if (propsRes->DictionarySize == 0)
propsRes->DictionarySize = 1;
}
#endif
return LZMA_RESULT_OK;
}
#define kLzmaStreamWasFinishedId (-1)
int LzmaDecode(CLzmaDecoderState *vs,
#ifdef _LZMA_IN_CB
ILzmaInCallback *InCallback,
#else
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
#endif
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
{
CProb *p = vs->Probs;
SizeT nowPos = 0;
Byte previousByte = 0;
UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
int lc = vs->Properties.lc;
#ifdef _LZMA_OUT_READ
UInt32 Range = vs->Range;
UInt32 Code = vs->Code;
#ifdef _LZMA_IN_CB
const Byte *Buffer = vs->Buffer;
const Byte *BufferLim = vs->BufferLim;
#else
const Byte *Buffer = inStream;
const Byte *BufferLim = inStream + inSize;
#endif
int state = vs->State;
UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
int len = vs->RemainLen;
UInt32 globalPos = vs->GlobalPos;
UInt32 distanceLimit = vs->DistanceLimit;
Byte *dictionary = vs->Dictionary;
UInt32 dictionarySize = vs->Properties.DictionarySize;
UInt32 dictionaryPos = vs->DictionaryPos;
Byte tempDictionary[4];
#ifndef _LZMA_IN_CB
*inSizeProcessed = 0;
#endif
*outSizeProcessed = 0;
if (len == kLzmaStreamWasFinishedId)
return LZMA_RESULT_OK;
if (dictionarySize == 0)
{
dictionary = tempDictionary;
dictionarySize = 1;
tempDictionary[0] = vs->TempDictionary[0];
}
if (len == kLzmaNeedInitId)
{
{
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
UInt32 i;
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
rep0 = rep1 = rep2 = rep3 = 1;
state = 0;
globalPos = 0;
distanceLimit = 0;
dictionaryPos = 0;
dictionary[dictionarySize - 1] = 0;
#ifdef _LZMA_IN_CB
RC_INIT;
#else
RC_INIT(inStream, inSize);
#endif
}
len = 0;
}
while(len != 0 && nowPos < outSize)
{
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
len--;
}
if (dictionaryPos == 0)
previousByte = dictionary[dictionarySize - 1];
else
previousByte = dictionary[dictionaryPos - 1];
#else /* if !_LZMA_OUT_READ */
int state = 0;
UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
int len = 0;
const Byte *Buffer;
const Byte *BufferLim;
UInt32 Range;
UInt32 Code;
#ifndef _LZMA_IN_CB
*inSizeProcessed = 0;
#endif
*outSizeProcessed = 0;
{
UInt32 i;
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
}
#ifdef _LZMA_IN_CB
RC_INIT;
#else
RC_INIT(inStream, inSize);
#endif
#endif /* _LZMA_OUT_READ */
while(nowPos < outSize)
{
CProb *prob;
UInt32 bound;
int posState = (int)(
(nowPos
#ifdef _LZMA_OUT_READ
+ globalPos
#endif
)
& posStateMask);
prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
IfBit0(prob)
{
int symbol = 1;
UpdateBit0(prob)
prob = p + Literal + (LZMA_LIT_SIZE *
(((
(nowPos
#ifdef _LZMA_OUT_READ
+ globalPos
#endif
)
& literalPosMask) << lc) + (previousByte >> (8 - lc))));
if (state >= kNumLitStates)
{
int matchByte;
#ifdef _LZMA_OUT_READ
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
matchByte = dictionary[pos];
#else
matchByte = outStream[nowPos - rep0];
#endif
do
{
int bit;
CProb *probLit;
matchByte <<= 1;
bit = (matchByte & 0x100);
probLit = prob + 0x100 + bit + symbol;
RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
}
while (symbol < 0x100);
}
while (symbol < 0x100)
{
CProb *probLit = prob + symbol;
RC_GET_BIT(probLit, symbol)
}
previousByte = (Byte)symbol;
outStream[nowPos++] = previousByte;
#ifdef _LZMA_OUT_READ
if (distanceLimit < dictionarySize)
distanceLimit++;
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#endif
if (state < 4) state = 0;
else if (state < 10) state -= 3;
else state -= 6;
}
else
{
UpdateBit1(prob);
prob = p + IsRep + state;
IfBit0(prob)
{
UpdateBit0(prob);
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
state = state < kNumLitStates ? 0 : 3;
prob = p + LenCoder;
}
else
{
UpdateBit1(prob);
prob = p + IsRepG0 + state;
IfBit0(prob)
{
UpdateBit0(prob);
prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
IfBit0(prob)
{
#ifdef _LZMA_OUT_READ
UInt32 pos;
#endif
UpdateBit0(prob);
#ifdef _LZMA_OUT_READ
if (distanceLimit == 0)
#else
if (nowPos == 0)
#endif
return LZMA_RESULT_DATA_ERROR;
state = state < kNumLitStates ? 9 : 11;
#ifdef _LZMA_OUT_READ
pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#else
previousByte = outStream[nowPos - rep0];
#endif
outStream[nowPos++] = previousByte;
#ifdef _LZMA_OUT_READ
if (distanceLimit < dictionarySize)
distanceLimit++;
#endif
continue;
}
else
{
UpdateBit1(prob);
}
}
else
{
UInt32 distance;
UpdateBit1(prob);
prob = p + IsRepG1 + state;
IfBit0(prob)
{
UpdateBit0(prob);
distance = rep1;
}
else
{
UpdateBit1(prob);
prob = p + IsRepG2 + state;
IfBit0(prob)
{
UpdateBit0(prob);
distance = rep2;
}
else
{
UpdateBit1(prob);
distance = rep3;
rep3 = rep2;
}
rep2 = rep1;
}
rep1 = rep0;
rep0 = distance;
}
state = state < kNumLitStates ? 8 : 11;
prob = p + RepLenCoder;
}
{
int numBits, offset;
CProb *probLen = prob + LenChoice;
IfBit0(probLen)
{
UpdateBit0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits);
offset = 0;
numBits = kLenNumLowBits;
}
else
{
UpdateBit1(probLen);
probLen = prob + LenChoice2;
IfBit0(probLen)
{
UpdateBit0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits);
offset = kLenNumLowSymbols;
numBits = kLenNumMidBits;
}
else
{
UpdateBit1(probLen);
probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols;
numBits = kLenNumHighBits;
}
}
RangeDecoderBitTreeDecode(probLen, numBits, len);
len += offset;
}
if (state < 4)
{
int posSlot;
state += kNumLitStates;
prob = p + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
kNumPosSlotBits);
RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex)
{
int numDirectBits = ((posSlot >> 1) - 1);
rep0 = (2 | ((UInt32)posSlot & 1));
if (posSlot < kEndPosModelIndex)
{
rep0 <<= numDirectBits;
prob = p + SpecPos + rep0 - posSlot - 1;
}
else
{
numDirectBits -= kNumAlignBits;
do
{
RC_NORMALIZE
Range >>= 1;
rep0 <<= 1;
if (Code >= Range)
{
Code -= Range;
rep0 |= 1;
}
}
while (--numDirectBits != 0);
prob = p + Align;
rep0 <<= kNumAlignBits;
numDirectBits = kNumAlignBits;
}
{
int i = 1;
int mi = 1;
do
{
CProb *prob3 = prob + mi;
RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
i <<= 1;
}
while(--numDirectBits != 0);
}
}
else
rep0 = posSlot;
if (++rep0 == (UInt32)(0))
{
/* it's for stream version */
len = kLzmaStreamWasFinishedId;
break;
}
}
len += kMatchMinLen;
#ifdef _LZMA_OUT_READ
if (rep0 > distanceLimit)
#else
if (rep0 > nowPos)
#endif
return LZMA_RESULT_DATA_ERROR;
#ifdef _LZMA_OUT_READ
if (dictionarySize - distanceLimit > (UInt32)len)
distanceLimit += len;
else
distanceLimit = dictionarySize;
#endif
do
{
#ifdef _LZMA_OUT_READ
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#else
previousByte = outStream[nowPos - rep0];
#endif
len--;
outStream[nowPos++] = previousByte;
}
while(len != 0 && nowPos < outSize);
}
}
RC_NORMALIZE;
#ifdef _LZMA_OUT_READ
vs->Range = Range;
vs->Code = Code;
vs->DictionaryPos = dictionaryPos;
vs->GlobalPos = globalPos + (UInt32)nowPos;
vs->DistanceLimit = distanceLimit;
vs->Reps[0] = rep0;
vs->Reps[1] = rep1;
vs->Reps[2] = rep2;
vs->Reps[3] = rep3;
vs->State = state;
vs->RemainLen = len;
vs->TempDictionary[0] = tempDictionary[0];
#endif
#ifdef _LZMA_IN_CB
vs->Buffer = Buffer;
vs->BufferLim = BufferLim;
#else
*inSizeProcessed = (SizeT)(Buffer - inStream);
#endif
*outSizeProcessed = nowPos;
return LZMA_RESULT_OK;
}

View File

@ -1,113 +0,0 @@
/*
LzmaDecode.h
LZMA Decoder interface
LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this code, expressly permits you to
statically or dynamically link your code (or bind by name) to the
interfaces of this file without subjecting your linked code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#ifndef __LZMADECODE_H
#define __LZMADECODE_H
#include "LzmaTypes.h"
/* #define _LZMA_IN_CB */
/* Use callback for input data */
/* #define _LZMA_OUT_READ */
/* Use read function for output data */
/* #define _LZMA_PROB32 */
/* It can increase speed on some 32-bit CPUs,
but memory usage will be doubled in that case */
/* #define _LZMA_LOC_OPT */
/* Enable local speed optimizations inside code */
#ifdef _LZMA_PROB32
#define CProb UInt32
#else
#define CProb UInt16
#endif
#define LZMA_RESULT_OK 0
#define LZMA_RESULT_DATA_ERROR 1
#ifdef _LZMA_IN_CB
typedef struct _ILzmaInCallback
{
int (*Read)(void *object, const unsigned char **buffer, SizeT *bufferSize);
} ILzmaInCallback;
#endif
#define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768
#define LZMA_PROPERTIES_SIZE 5
typedef struct _CLzmaProperties
{
int lc;
int lp;
int pb;
#ifdef _LZMA_OUT_READ
UInt32 DictionarySize;
#endif
}CLzmaProperties;
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
#define kLzmaNeedInitId (-2)
typedef struct _CLzmaDecoderState
{
CLzmaProperties Properties;
CProb *Probs;
#ifdef _LZMA_IN_CB
const unsigned char *Buffer;
const unsigned char *BufferLim;
#endif
#ifdef _LZMA_OUT_READ
unsigned char *Dictionary;
UInt32 Range;
UInt32 Code;
UInt32 DictionaryPos;
UInt32 GlobalPos;
UInt32 DistanceLimit;
UInt32 Reps[4];
int State;
int RemainLen;
unsigned char TempDictionary[4];
#endif
} CLzmaDecoderState;
#ifdef _LZMA_OUT_READ
#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; }
#endif
int LzmaDecode(CLzmaDecoderState *vs,
#ifdef _LZMA_IN_CB
ILzmaInCallback *inCallback,
#else
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
#endif
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed);
#endif

View File

@ -1,712 +0,0 @@
/*
LzmaDecodeSize.c
LZMA Decoder (optimized for Size version)
LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this code, expressly permits you to
statically or dynamically link your code (or bind by name) to the
interfaces of this file without subjecting your linked code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#include "LzmaDecode.h"
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kNumMoveBits 5
typedef struct _CRangeDecoder
{
const Byte *Buffer;
const Byte *BufferLim;
UInt32 Range;
UInt32 Code;
#ifdef _LZMA_IN_CB
ILzmaInCallback *InCallback;
int Result;
#endif
int ExtraBytes;
} CRangeDecoder;
Byte RangeDecoderReadByte(CRangeDecoder *rd)
{
if (rd->Buffer == rd->BufferLim)
{
#ifdef _LZMA_IN_CB
SizeT size;
rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size);
rd->BufferLim = rd->Buffer + size;
if (size == 0)
#endif
{
rd->ExtraBytes = 1;
return 0xFF;
}
}
return (*rd->Buffer++);
}
/* #define ReadByte (*rd->Buffer++) */
#define ReadByte (RangeDecoderReadByte(rd))
void RangeDecoderInit(CRangeDecoder *rd
#ifndef _LZMA_IN_CB
, const Byte *stream, SizeT bufferSize
#endif
)
{
int i;
#ifdef _LZMA_IN_CB
rd->Buffer = rd->BufferLim = 0;
#else
rd->Buffer = stream;
rd->BufferLim = stream + bufferSize;
#endif
rd->ExtraBytes = 0;
rd->Code = 0;
rd->Range = (0xFFFFFFFF);
for(i = 0; i < 5; i++)
rd->Code = (rd->Code << 8) | ReadByte;
}
#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code;
#define RC_FLUSH_VAR rd->Range = range; rd->Code = code;
#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; }
UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits)
{
RC_INIT_VAR
UInt32 result = 0;
int i;
for (i = numTotalBits; i != 0; i--)
{
/* UInt32 t; */
range >>= 1;
result <<= 1;
if (code >= range)
{
code -= range;
result |= 1;
}
/*
t = (code - range) >> 31;
t &= 1;
code -= range & (t - 1);
result = (result + result) | (1 - t);
*/
RC_NORMALIZE
}
RC_FLUSH_VAR
return result;
}
int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd)
{
UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob;
if (rd->Code < bound)
{
rd->Range = bound;
*prob += (kBitModelTotal - *prob) >> kNumMoveBits;
if (rd->Range < kTopValue)
{
rd->Code = (rd->Code << 8) | ReadByte;
rd->Range <<= 8;
}
return 0;
}
else
{
rd->Range -= bound;
rd->Code -= bound;
*prob -= (*prob) >> kNumMoveBits;
if (rd->Range < kTopValue)
{
rd->Code = (rd->Code << 8) | ReadByte;
rd->Range <<= 8;
}
return 1;
}
}
#define RC_GET_BIT2(prob, mi, A0, A1) \
UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \
if (code < bound) \
{ A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \
else \
{ A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \
RC_NORMALIZE
#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;)
int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
{
int mi = 1;
int i;
#ifdef _LZMA_LOC_OPT
RC_INIT_VAR
#endif
for(i = numLevels; i != 0; i--)
{
#ifdef _LZMA_LOC_OPT
CProb *prob = probs + mi;
RC_GET_BIT(prob, mi)
#else
mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd);
#endif
}
#ifdef _LZMA_LOC_OPT
RC_FLUSH_VAR
#endif
return mi - (1 << numLevels);
}
int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd)
{
int mi = 1;
int i;
int symbol = 0;
#ifdef _LZMA_LOC_OPT
RC_INIT_VAR
#endif
for(i = 0; i < numLevels; i++)
{
#ifdef _LZMA_LOC_OPT
CProb *prob = probs + mi;
RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i))
#else
int bit = RangeDecoderBitDecode(probs + mi, rd);
mi = mi + mi + bit;
symbol |= (bit << i);
#endif
}
#ifdef _LZMA_LOC_OPT
RC_FLUSH_VAR
#endif
return symbol;
}
Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd)
{
int symbol = 1;
#ifdef _LZMA_LOC_OPT
RC_INIT_VAR
#endif
do
{
#ifdef _LZMA_LOC_OPT
CProb *prob = probs + symbol;
RC_GET_BIT(prob, symbol)
#else
symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
#endif
}
while (symbol < 0x100);
#ifdef _LZMA_LOC_OPT
RC_FLUSH_VAR
#endif
return symbol;
}
Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte)
{
int symbol = 1;
#ifdef _LZMA_LOC_OPT
RC_INIT_VAR
#endif
do
{
int bit;
int matchBit = (matchByte >> 7) & 1;
matchByte <<= 1;
#ifdef _LZMA_LOC_OPT
{
CProb *prob = probs + 0x100 + (matchBit << 8) + symbol;
RC_GET_BIT2(prob, symbol, bit = 0, bit = 1)
}
#else
bit = RangeDecoderBitDecode(probs + 0x100 + (matchBit << 8) + symbol, rd);
symbol = (symbol << 1) | bit;
#endif
if (matchBit != bit)
{
while (symbol < 0x100)
{
#ifdef _LZMA_LOC_OPT
CProb *prob = probs + symbol;
RC_GET_BIT(prob, symbol)
#else
symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd);
#endif
}
break;
}
}
while (symbol < 0x100);
#ifdef _LZMA_LOC_OPT
RC_FLUSH_VAR
#endif
return symbol;
}
#define kNumPosBitsMax 4
#define kNumPosStatesMax (1 << kNumPosBitsMax)
#define kLenNumLowBits 3
#define kLenNumLowSymbols (1 << kLenNumLowBits)
#define kLenNumMidBits 3
#define kLenNumMidSymbols (1 << kLenNumMidBits)
#define kLenNumHighBits 8
#define kLenNumHighSymbols (1 << kLenNumHighBits)
#define LenChoice 0
#define LenChoice2 (LenChoice + 1)
#define LenLow (LenChoice2 + 1)
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState)
{
if(RangeDecoderBitDecode(p + LenChoice, rd) == 0)
return RangeDecoderBitTreeDecode(p + LenLow +
(posState << kLenNumLowBits), kLenNumLowBits, rd);
if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0)
return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid +
(posState << kLenNumMidBits), kLenNumMidBits, rd);
return kLenNumLowSymbols + kLenNumMidSymbols +
RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd);
}
#define kNumStates 12
#define kNumLitStates 7
#define kStartPosModelIndex 4
#define kEndPosModelIndex 14
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
#define kNumPosSlotBits 6
#define kNumLenToPosStates 4
#define kNumAlignBits 4
#define kAlignTableSize (1 << kNumAlignBits)
#define kMatchMinLen 2
#define IsMatch 0
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
#define IsRepG0 (IsRep + kNumStates)
#define IsRepG1 (IsRepG0 + kNumStates)
#define IsRepG2 (IsRepG1 + kNumStates)
#define IsRep0Long (IsRepG2 + kNumStates)
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
#define LenCoder (Align + kAlignTableSize)
#define RepLenCoder (LenCoder + kNumLenProbs)
#define Literal (RepLenCoder + kNumLenProbs)
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
{
unsigned char prop0;
if (size < LZMA_PROPERTIES_SIZE)
return LZMA_RESULT_DATA_ERROR;
prop0 = propsData[0];
if (prop0 >= (9 * 5 * 5))
return LZMA_RESULT_DATA_ERROR;
{
for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
propsRes->lc = prop0;
/*
unsigned char remainder = (unsigned char)(prop0 / 9);
propsRes->lc = prop0 % 9;
propsRes->pb = remainder / 5;
propsRes->lp = remainder % 5;
*/
}
#ifdef _LZMA_OUT_READ
{
int i;
propsRes->DictionarySize = 0;
for (i = 0; i < 4; i++)
propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
if (propsRes->DictionarySize == 0)
propsRes->DictionarySize = 1;
}
#endif
return LZMA_RESULT_OK;
}
#define kLzmaStreamWasFinishedId (-1)
int LzmaDecode(CLzmaDecoderState *vs,
#ifdef _LZMA_IN_CB
ILzmaInCallback *InCallback,
#else
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
#endif
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed)
{
CProb *p = vs->Probs;
SizeT nowPos = 0;
Byte previousByte = 0;
UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
int lc = vs->Properties.lc;
CRangeDecoder rd;
#ifdef _LZMA_OUT_READ
int state = vs->State;
UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
int len = vs->RemainLen;
UInt32 globalPos = vs->GlobalPos;
UInt32 distanceLimit = vs->DistanceLimit;
Byte *dictionary = vs->Dictionary;
UInt32 dictionarySize = vs->Properties.DictionarySize;
UInt32 dictionaryPos = vs->DictionaryPos;
Byte tempDictionary[4];
rd.Range = vs->Range;
rd.Code = vs->Code;
#ifdef _LZMA_IN_CB
rd.InCallback = InCallback;
rd.Buffer = vs->Buffer;
rd.BufferLim = vs->BufferLim;
#else
rd.Buffer = inStream;
rd.BufferLim = inStream + inSize;
#endif
#ifndef _LZMA_IN_CB
*inSizeProcessed = 0;
#endif
*outSizeProcessed = 0;
if (len == kLzmaStreamWasFinishedId)
return LZMA_RESULT_OK;
if (dictionarySize == 0)
{
dictionary = tempDictionary;
dictionarySize = 1;
tempDictionary[0] = vs->TempDictionary[0];
}
if (len == kLzmaNeedInitId)
{
{
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
UInt32 i;
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
rep0 = rep1 = rep2 = rep3 = 1;
state = 0;
globalPos = 0;
distanceLimit = 0;
dictionaryPos = 0;
dictionary[dictionarySize - 1] = 0;
RangeDecoderInit(&rd
#ifndef _LZMA_IN_CB
, inStream, inSize
#endif
);
#ifdef _LZMA_IN_CB
if (rd.Result != LZMA_RESULT_OK)
return rd.Result;
#endif
if (rd.ExtraBytes != 0)
return LZMA_RESULT_DATA_ERROR;
}
len = 0;
}
while(len != 0 && nowPos < outSize)
{
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
len--;
}
if (dictionaryPos == 0)
previousByte = dictionary[dictionarySize - 1];
else
previousByte = dictionary[dictionaryPos - 1];
#ifdef _LZMA_IN_CB
rd.Result = LZMA_RESULT_OK;
#endif
rd.ExtraBytes = 0;
#else /* if !_LZMA_OUT_READ */
int state = 0;
UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
int len = 0;
#ifndef _LZMA_IN_CB
*inSizeProcessed = 0;
#endif
*outSizeProcessed = 0;
{
UInt32 i;
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
}
#ifdef _LZMA_IN_CB
rd.InCallback = InCallback;
#endif
RangeDecoderInit(&rd
#ifndef _LZMA_IN_CB
, inStream, inSize
#endif
);
#ifdef _LZMA_IN_CB
if (rd.Result != LZMA_RESULT_OK)
return rd.Result;
#endif
if (rd.ExtraBytes != 0)
return LZMA_RESULT_DATA_ERROR;
#endif /* _LZMA_OUT_READ */
while(nowPos < outSize)
{
int posState = (int)(
(nowPos
#ifdef _LZMA_OUT_READ
+ globalPos
#endif
)
& posStateMask);
#ifdef _LZMA_IN_CB
if (rd.Result != LZMA_RESULT_OK)
return rd.Result;
#endif
if (rd.ExtraBytes != 0)
return LZMA_RESULT_DATA_ERROR;
if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0)
{
CProb *probs = p + Literal + (LZMA_LIT_SIZE *
(((
(nowPos
#ifdef _LZMA_OUT_READ
+ globalPos
#endif
)
& literalPosMask) << lc) + (previousByte >> (8 - lc))));
if (state >= kNumLitStates)
{
Byte matchByte;
#ifdef _LZMA_OUT_READ
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
matchByte = dictionary[pos];
#else
matchByte = outStream[nowPos - rep0];
#endif
previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte);
}
else
previousByte = LzmaLiteralDecode(probs, &rd);
outStream[nowPos++] = previousByte;
#ifdef _LZMA_OUT_READ
if (distanceLimit < dictionarySize)
distanceLimit++;
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#endif
if (state < 4) state = 0;
else if (state < 10) state -= 3;
else state -= 6;
}
else
{
if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1)
{
if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0)
{
if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0)
{
#ifdef _LZMA_OUT_READ
UInt32 pos;
#endif
#ifdef _LZMA_OUT_READ
if (distanceLimit == 0)
#else
if (nowPos == 0)
#endif
return LZMA_RESULT_DATA_ERROR;
state = state < 7 ? 9 : 11;
#ifdef _LZMA_OUT_READ
pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#else
previousByte = outStream[nowPos - rep0];
#endif
outStream[nowPos++] = previousByte;
#ifdef _LZMA_OUT_READ
if (distanceLimit < dictionarySize)
distanceLimit++;
#endif
continue;
}
}
else
{
UInt32 distance;
if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0)
distance = rep1;
else
{
if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0)
distance = rep2;
else
{
distance = rep3;
rep3 = rep2;
}
rep2 = rep1;
}
rep1 = rep0;
rep0 = distance;
}
len = LzmaLenDecode(p + RepLenCoder, &rd, posState);
state = state < 7 ? 8 : 11;
}
else
{
int posSlot;
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
state = state < 7 ? 7 : 10;
len = LzmaLenDecode(p + LenCoder, &rd, posState);
posSlot = RangeDecoderBitTreeDecode(p + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
kNumPosSlotBits), kNumPosSlotBits, &rd);
if (posSlot >= kStartPosModelIndex)
{
int numDirectBits = ((posSlot >> 1) - 1);
rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits);
if (posSlot < kEndPosModelIndex)
{
rep0 += RangeDecoderReverseBitTreeDecode(
p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd);
}
else
{
rep0 += RangeDecoderDecodeDirectBits(&rd,
numDirectBits - kNumAlignBits) << kNumAlignBits;
rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd);
}
}
else
rep0 = posSlot;
if (++rep0 == (UInt32)(0))
{
/* it's for stream version */
len = kLzmaStreamWasFinishedId;
break;
}
}
len += kMatchMinLen;
#ifdef _LZMA_OUT_READ
if (rep0 > distanceLimit)
#else
if (rep0 > nowPos)
#endif
return LZMA_RESULT_DATA_ERROR;
#ifdef _LZMA_OUT_READ
if (dictionarySize - distanceLimit > (UInt32)len)
distanceLimit += len;
else
distanceLimit = dictionarySize;
#endif
do
{
#ifdef _LZMA_OUT_READ
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
#else
previousByte = outStream[nowPos - rep0];
#endif
len--;
outStream[nowPos++] = previousByte;
}
while(len != 0 && nowPos < outSize);
}
}
#ifdef _LZMA_OUT_READ
vs->Range = rd.Range;
vs->Code = rd.Code;
vs->DictionaryPos = dictionaryPos;
vs->GlobalPos = globalPos + (UInt32)nowPos;
vs->DistanceLimit = distanceLimit;
vs->Reps[0] = rep0;
vs->Reps[1] = rep1;
vs->Reps[2] = rep2;
vs->Reps[3] = rep3;
vs->State = state;
vs->RemainLen = len;
vs->TempDictionary[0] = tempDictionary[0];
#endif
#ifdef _LZMA_IN_CB
vs->Buffer = rd.Buffer;
vs->BufferLim = rd.BufferLim;
#else
*inSizeProcessed = (SizeT)(rd.Buffer - inStream);
#endif
*outSizeProcessed = nowPos;
return LZMA_RESULT_OK;
}

View File

@ -1,521 +0,0 @@
/*
LzmaStateDecode.c
LZMA Decoder (State version)
LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this Code, expressly permits you to
statically or dynamically link your Code (or bind by name) to the
interfaces of this file without subjecting your linked Code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#include "LzmaStateDecode.h"
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kNumMoveBits 5
#define RC_READ_BYTE (*Buffer++)
#define RC_INIT Code = 0; Range = 0xFFFFFFFF; \
{ int i; for(i = 0; i < 5; i++) { Code = (Code << 8) | RC_READ_BYTE; }}
#define RC_NORMALIZE if (Range < kTopValue) { Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
{ UpdateBit0(p); mi <<= 1; A0; } else \
{ UpdateBit1(p); mi = (mi + mi) + 1; A1; }
#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
{ int i = numLevels; res = 1; \
do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
res -= (1 << numLevels); }
#define kNumPosBitsMax 4
#define kNumPosStatesMax (1 << kNumPosBitsMax)
#define kLenNumLowBits 3
#define kLenNumLowSymbols (1 << kLenNumLowBits)
#define kLenNumMidBits 3
#define kLenNumMidSymbols (1 << kLenNumMidBits)
#define kLenNumHighBits 8
#define kLenNumHighSymbols (1 << kLenNumHighBits)
#define LenChoice 0
#define LenChoice2 (LenChoice + 1)
#define LenLow (LenChoice2 + 1)
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
#define kNumStates 12
#define kNumLitStates 7
#define kStartPosModelIndex 4
#define kEndPosModelIndex 14
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
#define kNumPosSlotBits 6
#define kNumLenToPosStates 4
#define kNumAlignBits 4
#define kAlignTableSize (1 << kNumAlignBits)
#define kMatchMinLen 2
#define IsMatch 0
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
#define IsRepG0 (IsRep + kNumStates)
#define IsRepG1 (IsRepG0 + kNumStates)
#define IsRepG2 (IsRepG1 + kNumStates)
#define IsRep0Long (IsRepG2 + kNumStates)
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
#define LenCoder (Align + kAlignTableSize)
#define RepLenCoder (LenCoder + kNumLenProbs)
#define Literal (RepLenCoder + kNumLenProbs)
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif
/* kRequiredInBufferSize = number of required input bytes for worst case:
longest match with longest distance.
kLzmaInBufferSize must be larger than kRequiredInBufferSize
23 bits = 2 (match select) + 10 (len) + 6 (distance) + 4(align) + 1 (RC_NORMALIZE)
*/
#define kRequiredInBufferSize ((23 * (kNumBitModelTotalBits - kNumMoveBits + 1) + 26 + 9) / 8)
#define kLzmaStreamWasFinishedId (-1)
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
{
unsigned char prop0;
if (size < LZMA_PROPERTIES_SIZE)
return LZMA_RESULT_DATA_ERROR;
prop0 = propsData[0];
if (prop0 >= (9 * 5 * 5))
return LZMA_RESULT_DATA_ERROR;
{
for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
propsRes->lc = prop0;
/*
unsigned char remainder = (unsigned char)(prop0 / 9);
propsRes->lc = prop0 % 9;
propsRes->pb = remainder / 5;
propsRes->lp = remainder % 5;
*/
}
{
int i;
propsRes->DictionarySize = 0;
for (i = 0; i < 4; i++)
propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
if (propsRes->DictionarySize == 0)
propsRes->DictionarySize = 1;
return LZMA_RESULT_OK;
}
}
int LzmaDecode(
CLzmaDecoderState *vs,
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed,
int finishDecoding)
{
UInt32 Range = vs->Range;
UInt32 Code = vs->Code;
unsigned char *Buffer = vs->Buffer;
int BufferSize = vs->BufferSize; /* don't change it to unsigned int */
CProb *p = vs->Probs;
int state = vs->State;
unsigned char previousByte;
UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
SizeT nowPos = 0;
UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
int lc = vs->Properties.lc;
int len = vs->RemainLen;
UInt32 globalPos = vs->GlobalPos;
UInt32 distanceLimit = vs->DistanceLimit;
unsigned char *dictionary = vs->Dictionary;
UInt32 dictionarySize = vs->Properties.DictionarySize;
UInt32 dictionaryPos = vs->DictionaryPos;
unsigned char tempDictionary[4];
(*inSizeProcessed) = 0;
(*outSizeProcessed) = 0;
if (len == kLzmaStreamWasFinishedId)
return LZMA_RESULT_OK;
if (dictionarySize == 0)
{
dictionary = tempDictionary;
dictionarySize = 1;
tempDictionary[0] = vs->TempDictionary[0];
}
if (len == kLzmaNeedInitId)
{
while (inSize > 0 && BufferSize < kLzmaInBufferSize)
{
Buffer[BufferSize++] = *inStream++;
(*inSizeProcessed)++;
inSize--;
}
if (BufferSize < 5)
{
vs->BufferSize = BufferSize;
return finishDecoding ? LZMA_RESULT_DATA_ERROR : LZMA_RESULT_OK;
}
{
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
UInt32 i;
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
rep0 = rep1 = rep2 = rep3 = 1;
state = 0;
globalPos = 0;
distanceLimit = 0;
dictionaryPos = 0;
dictionary[dictionarySize - 1] = 0;
RC_INIT;
}
len = 0;
}
while(len != 0 && nowPos < outSize)
{
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
len--;
}
if (dictionaryPos == 0)
previousByte = dictionary[dictionarySize - 1];
else
previousByte = dictionary[dictionaryPos - 1];
for (;;)
{
int bufferPos = (int)(Buffer - vs->Buffer);
if (BufferSize - bufferPos < kRequiredInBufferSize)
{
int i;
BufferSize -= bufferPos;
if (BufferSize < 0)
return LZMA_RESULT_DATA_ERROR;
for (i = 0; i < BufferSize; i++)
vs->Buffer[i] = Buffer[i];
Buffer = vs->Buffer;
while (inSize > 0 && BufferSize < kLzmaInBufferSize)
{
Buffer[BufferSize++] = *inStream++;
(*inSizeProcessed)++;
inSize--;
}
if (BufferSize < kRequiredInBufferSize && !finishDecoding)
break;
}
if (nowPos >= outSize)
break;
{
CProb *prob;
UInt32 bound;
int posState = (int)((nowPos + globalPos) & posStateMask);
prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
IfBit0(prob)
{
int symbol = 1;
UpdateBit0(prob)
prob = p + Literal + (LZMA_LIT_SIZE *
((((nowPos + globalPos)& literalPosMask) << lc) + (previousByte >> (8 - lc))));
if (state >= kNumLitStates)
{
int matchByte;
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
matchByte = dictionary[pos];
do
{
int bit;
CProb *probLit;
matchByte <<= 1;
bit = (matchByte & 0x100);
probLit = prob + 0x100 + bit + symbol;
RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
}
while (symbol < 0x100);
}
while (symbol < 0x100)
{
CProb *probLit = prob + symbol;
RC_GET_BIT(probLit, symbol)
}
previousByte = (unsigned char)symbol;
outStream[nowPos++] = previousByte;
if (distanceLimit < dictionarySize)
distanceLimit++;
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
if (state < 4) state = 0;
else if (state < 10) state -= 3;
else state -= 6;
}
else
{
UpdateBit1(prob);
prob = p + IsRep + state;
IfBit0(prob)
{
UpdateBit0(prob);
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
state = state < kNumLitStates ? 0 : 3;
prob = p + LenCoder;
}
else
{
UpdateBit1(prob);
prob = p + IsRepG0 + state;
IfBit0(prob)
{
UpdateBit0(prob);
prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
IfBit0(prob)
{
UInt32 pos;
UpdateBit0(prob);
if (distanceLimit == 0)
return LZMA_RESULT_DATA_ERROR;
if (distanceLimit < dictionarySize)
distanceLimit++;
state = state < kNumLitStates ? 9 : 11;
pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
outStream[nowPos++] = previousByte;
continue;
}
else
{
UpdateBit1(prob);
}
}
else
{
UInt32 distance;
UpdateBit1(prob);
prob = p + IsRepG1 + state;
IfBit0(prob)
{
UpdateBit0(prob);
distance = rep1;
}
else
{
UpdateBit1(prob);
prob = p + IsRepG2 + state;
IfBit0(prob)
{
UpdateBit0(prob);
distance = rep2;
}
else
{
UpdateBit1(prob);
distance = rep3;
rep3 = rep2;
}
rep2 = rep1;
}
rep1 = rep0;
rep0 = distance;
}
state = state < kNumLitStates ? 8 : 11;
prob = p + RepLenCoder;
}
{
int numBits, offset;
CProb *probLen = prob + LenChoice;
IfBit0(probLen)
{
UpdateBit0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits);
offset = 0;
numBits = kLenNumLowBits;
}
else
{
UpdateBit1(probLen);
probLen = prob + LenChoice2;
IfBit0(probLen)
{
UpdateBit0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits);
offset = kLenNumLowSymbols;
numBits = kLenNumMidBits;
}
else
{
UpdateBit1(probLen);
probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols;
numBits = kLenNumHighBits;
}
}
RangeDecoderBitTreeDecode(probLen, numBits, len);
len += offset;
}
if (state < 4)
{
int posSlot;
state += kNumLitStates;
prob = p + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
kNumPosSlotBits);
RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex)
{
int numDirectBits = ((posSlot >> 1) - 1);
rep0 = (2 | ((UInt32)posSlot & 1));
if (posSlot < kEndPosModelIndex)
{
rep0 <<= numDirectBits;
prob = p + SpecPos + rep0 - posSlot - 1;
}
else
{
numDirectBits -= kNumAlignBits;
do
{
RC_NORMALIZE
Range >>= 1;
rep0 <<= 1;
if (Code >= Range)
{
Code -= Range;
rep0 |= 1;
}
}
while (--numDirectBits != 0);
prob = p + Align;
rep0 <<= kNumAlignBits;
numDirectBits = kNumAlignBits;
}
{
int i = 1;
int mi = 1;
do
{
CProb *prob3 = prob + mi;
RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
i <<= 1;
}
while(--numDirectBits != 0);
}
}
else
rep0 = posSlot;
if (++rep0 == (UInt32)(0))
{
/* it's for stream version */
len = kLzmaStreamWasFinishedId;
break;
}
}
len += kMatchMinLen;
if (rep0 > distanceLimit)
return LZMA_RESULT_DATA_ERROR;
if (dictionarySize - distanceLimit > (UInt32)len)
distanceLimit += len;
else
distanceLimit = dictionarySize;
do
{
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
len--;
outStream[nowPos++] = previousByte;
}
while(len != 0 && nowPos < outSize);
}
}
}
RC_NORMALIZE;
BufferSize -= (int)(Buffer - vs->Buffer);
if (BufferSize < 0)
return LZMA_RESULT_DATA_ERROR;
{
int i;
for (i = 0; i < BufferSize; i++)
vs->Buffer[i] = Buffer[i];
}
vs->BufferSize = BufferSize;
vs->Range = Range;
vs->Code = Code;
vs->DictionaryPos = dictionaryPos;
vs->GlobalPos = (UInt32)(globalPos + nowPos);
vs->DistanceLimit = distanceLimit;
vs->Reps[0] = rep0;
vs->Reps[1] = rep1;
vs->Reps[2] = rep2;
vs->Reps[3] = rep3;
vs->State = state;
vs->RemainLen = len;
vs->TempDictionary[0] = tempDictionary[0];
(*outSizeProcessed) = nowPos;
return LZMA_RESULT_OK;
}

View File

@ -1,96 +0,0 @@
/*
LzmaStateDecode.h
LZMA Decoder interface (State version)
LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this code, expressly permits you to
statically or dynamically link your code (or bind by name) to the
interfaces of this file without subjecting your linked code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#ifndef __LZMASTATEDECODE_H
#define __LZMASTATEDECODE_H
#include "LzmaTypes.h"
/* #define _LZMA_PROB32 */
/* It can increase speed on some 32-bit CPUs,
but memory usage will be doubled in that case */
#ifdef _LZMA_PROB32
#define CProb UInt32
#else
#define CProb UInt16
#endif
#define LZMA_RESULT_OK 0
#define LZMA_RESULT_DATA_ERROR 1
#define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768
#define LZMA_PROPERTIES_SIZE 5
typedef struct _CLzmaProperties
{
int lc;
int lp;
int pb;
UInt32 DictionarySize;
}CLzmaProperties;
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
#define LzmaGetNumProbs(lzmaProps) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((lzmaProps)->lc + (lzmaProps)->lp)))
#define kLzmaInBufferSize 64 /* don't change it. it must be larger than kRequiredInBufferSize */
#define kLzmaNeedInitId (-2)
typedef struct _CLzmaDecoderState
{
CLzmaProperties Properties;
CProb *Probs;
unsigned char *Dictionary;
unsigned char Buffer[kLzmaInBufferSize];
int BufferSize;
UInt32 Range;
UInt32 Code;
UInt32 DictionaryPos;
UInt32 GlobalPos;
UInt32 DistanceLimit;
UInt32 Reps[4];
int State;
int RemainLen; /* -2: decoder needs internal initialization
-1: stream was finished,
0: ok
> 0: need to write RemainLen bytes as match Reps[0],
*/
unsigned char TempDictionary[4]; /* it's required when DictionarySize = 0 */
} CLzmaDecoderState;
#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; (vs)->BufferSize = 0; }
/* LzmaDecode: decoding from input stream to output stream.
If finishDecoding != 0, then there are no more bytes in input stream
after inStream[inSize - 1]. */
int LzmaDecode(CLzmaDecoderState *vs,
const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed,
unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed,
int finishDecoding);
#endif

View File

@ -1,195 +0,0 @@
/*
LzmaStateTest.c
Test application for LZMA Decoder (State version)
This file written and distributed to public domain by Igor Pavlov.
This file is part of LZMA SDK 4.26 (2005-08-02)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "LzmaStateDecode.h"
const char *kCantReadMessage = "Can not read input file";
const char *kCantWriteMessage = "Can not write output file";
const char *kCantAllocateMessage = "Can not allocate memory";
#define kInBufferSize (1 << 15)
#define kOutBufferSize (1 << 15)
unsigned char g_InBuffer[kInBufferSize];
unsigned char g_OutBuffer[kOutBufferSize];
size_t MyReadFile(FILE *file, void *data, size_t size)
{ return fread(data, 1, size, file); }
int MyReadFileAndCheck(FILE *file, void *data, size_t size)
{ return (MyReadFile(file, data, size) == size); }
int PrintError(char *buffer, const char *message)
{
sprintf(buffer + strlen(buffer), "\nError: ");
sprintf(buffer + strlen(buffer), message);
return 1;
}
int main3(FILE *inFile, FILE *outFile, char *rs)
{
/* We use two 32-bit integers to construct 64-bit integer for file size.
You can remove outSizeHigh, if you don't need >= 4GB supporting,
or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
UInt32 outSize = 0;
UInt32 outSizeHigh = 0;
int waitEOS = 1;
/* waitEOS = 1, if there is no uncompressed size in headers,
so decoder will wait EOS (End of Stream Marker) in compressed stream */
int i;
int res = 0;
CLzmaDecoderState state; /* it's about 140 bytes structure, if int is 32-bit */
unsigned char properties[LZMA_PROPERTIES_SIZE];
SizeT inAvail = 0;
unsigned char *inBuffer = 0;
if (sizeof(UInt32) < 4)
return PrintError(rs, "LZMA decoder needs correct UInt32");
/* Read LZMA properties for compressed stream */
if (!MyReadFileAndCheck(inFile, properties, sizeof(properties)))
return PrintError(rs, kCantReadMessage);
/* Read uncompressed size */
for (i = 0; i < 8; i++)
{
unsigned char b;
if (!MyReadFileAndCheck(inFile, &b, 1))
return PrintError(rs, kCantReadMessage);
if (b != 0xFF)
waitEOS = 0;
if (i < 4)
outSize += (UInt32)(b) << (i * 8);
else
outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
}
/* Decode LZMA properties and allocate memory */
if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
return PrintError(rs, "Incorrect stream properties");
state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
if (state.Probs == 0)
return PrintError(rs, kCantAllocateMessage);
if (state.Properties.DictionarySize == 0)
state.Dictionary = 0;
else
{
state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
if (state.Dictionary == 0)
{
free(state.Probs);
return PrintError(rs, kCantAllocateMessage);
}
}
/* Decompress */
LzmaDecoderInit(&state);
do
{
SizeT inProcessed, outProcessed;
int finishDecoding;
UInt32 outAvail = kOutBufferSize;
if (!waitEOS && outSizeHigh == 0 && outAvail > outSize)
outAvail = outSize;
if (inAvail == 0)
{
inAvail = (SizeT)MyReadFile(inFile, g_InBuffer, kInBufferSize);
inBuffer = g_InBuffer;
}
finishDecoding = (inAvail == 0);
res = LzmaDecode(&state,
inBuffer, inAvail, &inProcessed,
g_OutBuffer, outAvail, &outProcessed,
finishDecoding);
if (res != 0)
{
sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
res = 1;
break;
}
inAvail -= inProcessed;
inBuffer += inProcessed;
if (outFile != 0)
if (fwrite(g_OutBuffer, 1, outProcessed, outFile) != outProcessed)
{
PrintError(rs, kCantWriteMessage);
res = 1;
break;
}
if (outSize < outProcessed)
outSizeHigh--;
outSize -= (UInt32)outProcessed;
outSize &= 0xFFFFFFFF;
if (outProcessed == 0 && finishDecoding)
{
if (!waitEOS && (outSize != 0 || outSizeHigh != 0))
res = 1;
break;
}
}
while ((outSize != 0 && outSizeHigh == 0) || outSizeHigh != 0 || waitEOS);
free(state.Dictionary);
free(state.Probs);
return res;
}
int main2(int numArgs, const char *args[], char *rs)
{
FILE *inFile = 0;
FILE *outFile = 0;
int res;
sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-02\n");
if (numArgs < 2 || numArgs > 3)
{
sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n");
return 1;
}
inFile = fopen(args[1], "rb");
if (inFile == 0)
return PrintError(rs, "Can not open input file");
if (numArgs > 2)
{
outFile = fopen(args[2], "wb+");
if (outFile == 0)
return PrintError(rs, "Can not open output file");
}
res = main3(inFile, outFile, rs);
if (outFile != 0)
fclose(outFile);
fclose(inFile);
return res;
}
int main(int numArgs, const char *args[])
{
char rs[800] = { 0 };
int res = main2(numArgs, args, rs);
printf(rs);
return res;
}

View File

@ -1,342 +0,0 @@
/*
LzmaTest.c
Test application for LZMA Decoder
This file written and distributed to public domain by Igor Pavlov.
This file is part of LZMA SDK 4.26 (2005-08-05)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "LzmaDecode.h"
const char *kCantReadMessage = "Can not read input file";
const char *kCantWriteMessage = "Can not write output file";
const char *kCantAllocateMessage = "Can not allocate memory";
size_t MyReadFile(FILE *file, void *data, size_t size)
{
if (size == 0)
return 0;
return fread(data, 1, size, file);
}
int MyReadFileAndCheck(FILE *file, void *data, size_t size)
{ return (MyReadFile(file, data, size) == size);}
size_t MyWriteFile(FILE *file, const void *data, size_t size)
{
if (size == 0)
return 0;
return fwrite(data, 1, size, file);
}
int MyWriteFileAndCheck(FILE *file, const void *data, size_t size)
{ return (MyWriteFile(file, data, size) == size); }
#ifdef _LZMA_IN_CB
#define kInBufferSize (1 << 15)
typedef struct _CBuffer
{
ILzmaInCallback InCallback;
FILE *File;
unsigned char Buffer[kInBufferSize];
} CBuffer;
int LzmaReadCompressed(void *object, const unsigned char **buffer, SizeT *size)
{
CBuffer *b = (CBuffer *)object;
*buffer = b->Buffer;
*size = (SizeT)MyReadFile(b->File, b->Buffer, kInBufferSize);
return LZMA_RESULT_OK;
}
CBuffer g_InBuffer;
#endif
#ifdef _LZMA_OUT_READ
#define kOutBufferSize (1 << 15)
unsigned char g_OutBuffer[kOutBufferSize];
#endif
int PrintError(char *buffer, const char *message)
{
sprintf(buffer + strlen(buffer), "\nError: ");
sprintf(buffer + strlen(buffer), message);
return 1;
}
int main3(FILE *inFile, FILE *outFile, char *rs)
{
/* We use two 32-bit integers to construct 64-bit integer for file size.
You can remove outSizeHigh, if you don't need >= 4GB supporting,
or you can use UInt64 outSize, if your compiler supports 64-bit integers*/
UInt32 outSize = 0;
UInt32 outSizeHigh = 0;
#ifndef _LZMA_OUT_READ
SizeT outSizeFull;
unsigned char *outStream;
#endif
int waitEOS = 1;
/* waitEOS = 1, if there is no uncompressed size in headers,
so decoder will wait EOS (End of Stream Marker) in compressed stream */
#ifndef _LZMA_IN_CB
SizeT compressedSize;
unsigned char *inStream;
#endif
CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
unsigned char properties[LZMA_PROPERTIES_SIZE];
int res;
#ifdef _LZMA_IN_CB
g_InBuffer.File = inFile;
#endif
if (sizeof(UInt32) < 4)
return PrintError(rs, "LZMA decoder needs correct UInt32");
#ifndef _LZMA_IN_CB
{
long length;
fseek(inFile, 0, SEEK_END);
length = ftell(inFile);
fseek(inFile, 0, SEEK_SET);
if ((long)(SizeT)length != length)
return PrintError(rs, "Too big compressed stream");
compressedSize = (SizeT)(length - (LZMA_PROPERTIES_SIZE + 8));
}
#endif
/* Read LZMA properties for compressed stream */
if (!MyReadFileAndCheck(inFile, properties, sizeof(properties)))
return PrintError(rs, kCantReadMessage);
/* Read uncompressed size */
{
int i;
for (i = 0; i < 8; i++)
{
unsigned char b;
if (!MyReadFileAndCheck(inFile, &b, 1))
return PrintError(rs, kCantReadMessage);
if (b != 0xFF)
waitEOS = 0;
if (i < 4)
outSize += (UInt32)(b) << (i * 8);
else
outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
}
#ifndef _LZMA_OUT_READ
if (waitEOS)
return PrintError(rs, "Stream with EOS marker is not supported");
outSizeFull = (SizeT)outSize;
if (sizeof(SizeT) >= 8)
outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize)
return PrintError(rs, "Too big uncompressed stream");
#endif
}
/* Decode LZMA properties and allocate memory */
if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK)
return PrintError(rs, "Incorrect stream properties");
state.Probs = (CProb *)malloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
#ifdef _LZMA_OUT_READ
if (state.Properties.DictionarySize == 0)
state.Dictionary = 0;
else
state.Dictionary = (unsigned char *)malloc(state.Properties.DictionarySize);
#else
if (outSizeFull == 0)
outStream = 0;
else
outStream = (unsigned char *)malloc(outSizeFull);
#endif
#ifndef _LZMA_IN_CB
if (compressedSize == 0)
inStream = 0;
else
inStream = (unsigned char *)malloc(compressedSize);
#endif
if (state.Probs == 0
#ifdef _LZMA_OUT_READ
|| (state.Dictionary == 0 && state.Properties.DictionarySize != 0)
#else
|| (outStream == 0 && outSizeFull != 0)
#endif
#ifndef _LZMA_IN_CB
|| (inStream == 0 && compressedSize != 0)
#endif
)
{
free(state.Probs);
#ifdef _LZMA_OUT_READ
free(state.Dictionary);
#else
free(outStream);
#endif
#ifndef _LZMA_IN_CB
free(inStream);
#endif
return PrintError(rs, kCantAllocateMessage);
}
/* Decompress */
#ifdef _LZMA_IN_CB
g_InBuffer.InCallback.Read = LzmaReadCompressed;
#else
if (!MyReadFileAndCheck(inFile, inStream, compressedSize))
return PrintError(rs, kCantReadMessage);
#endif
#ifdef _LZMA_OUT_READ
{
#ifndef _LZMA_IN_CB
SizeT inAvail = compressedSize;
const unsigned char *inBuffer = inStream;
#endif
LzmaDecoderInit(&state);
do
{
#ifndef _LZMA_IN_CB
SizeT inProcessed;
#endif
SizeT outProcessed;
SizeT outAvail = kOutBufferSize;
if (!waitEOS && outSizeHigh == 0 && outAvail > outSize)
outAvail = (SizeT)outSize;
res = LzmaDecode(&state,
#ifdef _LZMA_IN_CB
&g_InBuffer.InCallback,
#else
inBuffer, inAvail, &inProcessed,
#endif
g_OutBuffer, outAvail, &outProcessed);
if (res != 0)
{
sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
res = 1;
break;
}
#ifndef _LZMA_IN_CB
inAvail -= inProcessed;
inBuffer += inProcessed;
#endif
if (outFile != 0)
if (!MyWriteFileAndCheck(outFile, g_OutBuffer, (size_t)outProcessed))
{
PrintError(rs, kCantWriteMessage);
res = 1;
break;
}
if (outSize < outProcessed)
outSizeHigh--;
outSize -= (UInt32)outProcessed;
outSize &= 0xFFFFFFFF;
if (outProcessed == 0)
{
if (!waitEOS && (outSize != 0 || outSizeHigh != 0))
res = 1;
break;
}
}
while ((outSize != 0 && outSizeHigh == 0) || outSizeHigh != 0 || waitEOS);
}
#else
{
#ifndef _LZMA_IN_CB
SizeT inProcessed;
#endif
SizeT outProcessed;
res = LzmaDecode(&state,
#ifdef _LZMA_IN_CB
&g_InBuffer.InCallback,
#else
inStream, compressedSize, &inProcessed,
#endif
outStream, outSizeFull, &outProcessed);
if (res != 0)
{
sprintf(rs + strlen(rs), "\nDecoding error = %d\n", res);
res = 1;
}
else if (outFile != 0)
{
if (!MyWriteFileAndCheck(outFile, outStream, (size_t)outProcessed))
{
PrintError(rs, kCantWriteMessage);
res = 1;
}
}
}
#endif
free(state.Probs);
#ifdef _LZMA_OUT_READ
free(state.Dictionary);
#else
free(outStream);
#endif
#ifndef _LZMA_IN_CB
free(inStream);
#endif
return res;
}
int main2(int numArgs, const char *args[], char *rs)
{
FILE *inFile = 0;
FILE *outFile = 0;
int res;
sprintf(rs + strlen(rs), "\nLZMA Decoder 4.26 Copyright (c) 1999-2005 Igor Pavlov 2005-08-05\n");
if (numArgs < 2 || numArgs > 3)
{
sprintf(rs + strlen(rs), "\nUsage: lzmadec file.lzma [outFile]\n");
return 1;
}
inFile = fopen(args[1], "rb");
if (inFile == 0)
return PrintError(rs, "Can not open input file");
if (numArgs > 2)
{
outFile = fopen(args[2], "wb+");
if (outFile == 0)
return PrintError(rs, "Can not open output file");
}
res = main3(inFile, outFile, rs);
if (outFile != 0)
fclose(outFile);
fclose(inFile);
return res;
}
int main(int numArgs, const char *args[])
{
char rs[800] = { 0 };
int res = main2(numArgs, args, rs);
printf(rs);
return res;
}

View File

@ -1,45 +0,0 @@
/*
LzmaTypes.h
Types for LZMA Decoder
This file written and distributed to public domain by Igor Pavlov.
This file is part of LZMA SDK 4.40 (2006-05-01)
*/
#ifndef __LZMATYPES_H
#define __LZMATYPES_H
#ifndef _7ZIP_BYTE_DEFINED
#define _7ZIP_BYTE_DEFINED
typedef unsigned char Byte;
#endif
#ifndef _7ZIP_UINT16_DEFINED
#define _7ZIP_UINT16_DEFINED
typedef unsigned short UInt16;
#endif
#ifndef _7ZIP_UINT32_DEFINED
#define _7ZIP_UINT32_DEFINED
#ifdef _LZMA_UINT32_IS_ULONG
typedef unsigned long UInt32;
#else
typedef unsigned int UInt32;
#endif
#endif
/* #define _LZMA_NO_SYSTEM_SIZE_T */
/* You can use it, if you don't want <stddef.h> */
#ifndef _7ZIP_SIZET_DEFINED
#define _7ZIP_SIZET_DEFINED
#ifdef _LZMA_NO_SYSTEM_SIZE_T
typedef UInt32 SizeT;
#else
#include <stddef.h>
typedef size_t SizeT;
#endif
#endif
#endif

View File

@ -1,18 +0,0 @@
/* CpuArch.h */
#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
#endif

View File

@ -1,19 +0,0 @@
/* IStream.h */
#ifndef __C_ISTREAM_H
#define __C_ISTREAM_H
#include "Types.h"
typedef struct _ISeqInStream
{
HRes (*Read)(void *object, void *data, UInt32 size, UInt32 *processedSize);
} ISeqInStream;
typedef struct _ISzAlloc
{
void *(*Alloc)(size_t size);
void (*Free)(void *address); /* address can be 0 */
} ISzAlloc;
#endif

View File

@ -1,92 +0,0 @@
/* Sort.c */
#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);
}
*/

View File

@ -1,11 +0,0 @@
/* Sort.h */
#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

View File

@ -1,106 +0,0 @@
/* Threads.c */
#include "Threads.h"
#include <process.h>
HRes GetError()
{
DWORD res = GetLastError();
return (res) ? (HRes)(res) : SZE_FAIL;
}
HRes BoolToHRes(int v) { return v ? SZ_OK : GetError(); }
HRes BOOLToHRes(BOOL v) { return v ? SZ_OK : GetError(); }
HRes MyCloseHandle(HANDLE *h)
{
if (*h != NULL)
if (!CloseHandle(*h))
return GetError();
*h = NULL;
return SZ_OK;
}
HRes 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 BoolToHRes(thread->handle != 0);
}
HRes WaitObject(HANDLE h)
{
return (HRes)WaitForSingleObject(h, INFINITE);
}
HRes Thread_Wait(CThread *thread)
{
if (thread->handle == NULL)
return 1;
return WaitObject(thread->handle);
}
HRes Thread_Close(CThread *thread)
{
return MyCloseHandle(&thread->handle);
}
HRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled)
{
p->handle = CreateEvent(NULL, manualReset, (initialSignaled ? TRUE : FALSE), NULL);
return BoolToHRes(p->handle != 0);
}
HRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled)
{ return Event_Create(p, TRUE, initialSignaled); }
HRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p)
{ return ManualResetEvent_Create(p, 0); }
HRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled)
{ return Event_Create(p, FALSE, initialSignaled); }
HRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p)
{ return AutoResetEvent_Create(p, 0); }
HRes Event_Set(CEvent *p) { return BOOLToHRes(SetEvent(p->handle)); }
HRes Event_Reset(CEvent *p) { return BOOLToHRes(ResetEvent(p->handle)); }
HRes Event_Wait(CEvent *p) { return WaitObject(p->handle); }
HRes Event_Close(CEvent *p) { return MyCloseHandle(&p->handle); }
HRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount)
{
p->handle = CreateSemaphore(NULL, (LONG)initiallyCount, (LONG)maxCount, NULL);
return BoolToHRes(p->handle != 0);
}
HRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
{
return BOOLToHRes(ReleaseSemaphore(p->handle, releaseCount, previousCount));
}
HRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount)
{
return Semaphore_Release(p, (LONG)releaseCount, NULL);
}
HRes Semaphore_Release1(CSemaphore *p)
{
return Semaphore_ReleaseN(p, 1);
}
HRes Semaphore_Wait(CSemaphore *p) { return WaitObject(p->handle); }
HRes Semaphore_Close(CSemaphore *p) { return MyCloseHandle(&p->handle); }
HRes CriticalSection_Init(CCriticalSection *p)
{
/* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
__try
{
InitializeCriticalSection(p);
/* InitializeCriticalSectionAndSpinCount(p, 0); */
}
__except (EXCEPTION_EXECUTE_HANDLER) { return SZE_OUTOFMEMORY; }
return SZ_OK;
}

View File

@ -1,69 +0,0 @@
/* Threads.h */
#ifndef __7Z_THRESDS_H
#define __7Z_THRESDS_H
#include <windows.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 StdCall
#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
HRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter);
HRes Thread_Wait(CThread *thread);
HRes 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)
HRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled);
HRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event);
HRes AutoResetEvent_Create(CAutoResetEvent *event, int initialSignaled);
HRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *event);
HRes Event_Set(CEvent *event);
HRes Event_Reset(CEvent *event);
HRes Event_Wait(CEvent *event);
HRes Event_Close(CEvent *event);
typedef struct _CSemaphore
{
HANDLE handle;
} CSemaphore;
#define Semaphore_Construct(p) (p)->handle = NULL
HRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount);
HRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
HRes Semaphore_Release1(CSemaphore *p);
HRes Semaphore_Wait(CSemaphore *p);
HRes Semaphore_Close(CSemaphore *p);
typedef CRITICAL_SECTION CCriticalSection;
HRes CriticalSection_Init(CCriticalSection *p);
#define CriticalSection_Delete(p) DeleteCriticalSection(p)
#define CriticalSection_Enter(p) EnterCriticalSection(p)
#define CriticalSection_Leave(p) LeaveCriticalSection(p)
#endif

View File

@ -1,100 +0,0 @@
/* 7zTypes.h */
#ifndef __C_TYPES_H
#define __C_TYPES_H
#ifndef _7ZIP_BYTE_DEFINED
#define _7ZIP_BYTE_DEFINED
typedef unsigned char Byte;
#endif
#ifndef _7ZIP_UINT16_DEFINED
#define _7ZIP_UINT16_DEFINED
typedef unsigned short UInt16;
#endif
#ifndef _7ZIP_UINT32_DEFINED
#define _7ZIP_UINT32_DEFINED
#ifdef _LZMA_UINT32_IS_ULONG
typedef unsigned long UInt32;
#else
typedef unsigned int UInt32;
#endif
#endif
#ifndef _7ZIP_INT32_DEFINED
#define _7ZIP_INT32_DEFINED
#ifdef _LZMA_INT32_IS_ULONG
typedef long Int32;
#else
typedef int Int32;
#endif
#endif
/* #define _SZ_NO_INT_64 */
/* define it your compiler doesn't support long long int */
#ifndef _7ZIP_UINT64_DEFINED
#define _7ZIP_UINT64_DEFINED
#ifdef _SZ_NO_INT_64
typedef unsigned long UInt64;
#else
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 UInt64;
#else
typedef unsigned long long int UInt64;
#endif
#endif
#endif
/* #define _SZ_FILE_SIZE_32 */
/* You can define _SZ_FILE_SIZE_32, if you don't need support for files larger than 4 GB*/
#ifndef CFileSize
#ifdef _SZ_FILE_SIZE_32
typedef UInt32 CFileSize;
#else
typedef UInt64 CFileSize;
#endif
#endif
#define SZ_RESULT int
typedef int HRes;
#define RES_OK (0)
#define SZ_OK (0)
#define SZE_DATA_ERROR (1)
#define SZE_CRC_ERROR (3)
#define SZE_ARCHIVE_ERROR (6)
#define SZE_OUTOFMEMORY (0x8007000EL)
#define SZE_NOTIMPL (0x80004001L)
#define SZE_FAIL (0x80004005L)
#define SZE_INVALIDARG (0x80070057L)
#ifndef RINOK
#define RINOK(x) { HRes __result_ = (x); if(__result_ != 0) return __result_; }
#endif
typedef int Bool;
#define True 1
#define False 0
#ifdef _MSC_VER
#define StdCall __stdcall
#else
#define StdCall
#endif
#if _MSC_VER >= 1300
#define MY_FAST_CALL __declspec(noinline) __fastcall
#elif defined( _MSC_VER)
#define MY_FAST_CALL __fastcall
#else
#define MY_FAST_CALL
#endif
#endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -1,3 +0,0 @@
// CompressionMethod.cpp
#include "StdAfx.h"

View File

@ -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

View File

@ -1,330 +0,0 @@
// 7zDecode.cpp
#include "StdAfx.h"
#include "7zDecode.h"
#include "../../IPassword.h"
#include "../../Common/LockedStream.h"
#include "../../Common/StreamObjects.h"
#include "../../Common/ProgressUtils.h"
#include "../../Common/LimitedStreams.h"
#include "../../Common/CreateCoder.h"
#include "../../Common/FilterCoder.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
#endif
#ifdef COMPRESS_MT
, bool mtMode, UInt32 numThreads
#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 &properties = coderInfo.Properties;
size_t size = properties.GetCapacity();
if (size > 0xFFFFFFFF)
return E_NOTIMPL;
if (size > 0)
{
RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)properties, (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 password;
RINOK(getTextPassword->CryptoGetTextPassword(&password));
CByteBuffer buffer;
UString unicodePassword(password);
const UInt32 sizeInBytes = unicodePassword.Length() * 2;
buffer.SetCapacity(sizeInBytes);
for (int i = 0; i < unicodePassword.Length(); i++)
{
wchar_t c = unicodePassword[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);
}
}}

View File

@ -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
#endif
#ifdef COMPRESS_MT
, bool mtMode, UInt32 numThreads
#endif
);
};
}}
#endif

View File

@ -1,453 +0,0 @@
// Encode.cpp
#include "StdAfx.h"
#include "7zEncode.h"
#include "7zSpecStream.h"
#include "../../IPassword.h"
#include "../../Common/ProgressUtils.h"
#include "../../Common/LimitedStreams.h"
#include "../../Common/InOutTempBuffer.h"
#include "../../Common/StreamObjects.h"
#include "../../Common/CreateCoder.h"
#include "../../Common/FilterCoder.h"
static const UInt64 k_AES = 0x06F10701;
static const UInt64 k_BCJ = 0x03030103;
static const UInt64 k_BCJ2 = 0x0303011B;
namespace NArchive {
namespace N7z {
static void ConvertBindInfoToFolderItemInfo(const NCoderMixer::CBindInfo &bindInfo,
const CRecordVector<CMethodId> decompressionMethods,
CFolder &folder)
{
folder.Coders.Clear();
// bindInfo.CoderMethodIDs.Clear();
// folder.OutStreams.Clear();
folder.PackStreams.Clear();
folder.BindPairs.Clear();
int i;
for (i = 0; i < bindInfo.BindPairs.Size(); i++)
{
CBindPair bindPair;
bindPair.InIndex = bindInfo.BindPairs[i].InIndex;
bindPair.OutIndex = bindInfo.BindPairs[i].OutIndex;
folder.BindPairs.Add(bindPair);
}
for (i = 0; i < bindInfo.Coders.Size(); i++)
{
CCoderInfo coderInfo;
const NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i];
coderInfo.NumInStreams = coderStreamsInfo.NumInStreams;
coderInfo.NumOutStreams = coderStreamsInfo.NumOutStreams;
coderInfo.MethodID = decompressionMethods[i];
folder.Coders.Add(coderInfo);
}
for (i = 0; i < bindInfo.InStreams.Size(); i++)
folder.PackStreams.Add(bindInfo.InStreams[i]);
}
HRESULT CEncoder::CreateMixerCoder(
DECL_EXTERNAL_CODECS_LOC_VARS
const UInt64 *inSizeForReduce)
{
_mixerCoderSpec = new NCoderMixer::CCoderMixer2MT;
_mixerCoder = _mixerCoderSpec;
RINOK(_mixerCoderSpec->SetBindInfo(_bindInfo));
for (int i = 0; i < _options.Methods.Size(); i++)
{
const CMethodFull &methodFull = _options.Methods[i];
_codersInfo.Add(CCoderInfo());
CCoderInfo &encodingInfo = _codersInfo.Back();
encodingInfo.MethodID = methodFull.Id;
CMyComPtr<ICompressCoder> encoder;
CMyComPtr<ICompressCoder2> encoder2;
RINOK(CreateCoder(
EXTERNAL_CODECS_LOC_VARS
methodFull.Id, encoder, encoder2, true));
if (!encoder && !encoder2)
return E_FAIL;
CMyComPtr<IUnknown> encoderCommon = encoder ? (IUnknown *)encoder : (IUnknown *)encoder2;
#ifdef COMPRESS_MT
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
encoderCommon.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
if (setCoderMt)
{
RINOK(setCoderMt->SetNumberOfThreads(_options.NumThreads));
}
}
#endif
RINOK(SetMethodProperties(methodFull, inSizeForReduce, encoderCommon));
/*
CMyComPtr<ICryptoResetSalt> resetSalt;
encoderCommon.QueryInterface(IID_ICryptoResetSalt, (void **)&resetSalt);
if (resetSalt != NULL)
{
resetSalt->ResetSalt();
}
*/
#ifdef EXTERNAL_CODECS
CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
if (setCompressCodecsInfo)
{
RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo));
}
#endif
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
if (cryptoSetPassword)
{
CByteBuffer buffer;
const UInt32 sizeInBytes = _options.Password.Length() * 2;
buffer.SetCapacity(sizeInBytes);
for (int i = 0; i < _options.Password.Length(); i++)
{
wchar_t c = _options.Password[i];
((Byte *)buffer)[i * 2] = (Byte)c;
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
}
RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
}
if (encoder)
_mixerCoderSpec->AddCoder(encoder);
else
_mixerCoderSpec->AddCoder2(encoder2);
}
return S_OK;
}
HRESULT CEncoder::Encode(
DECL_EXTERNAL_CODECS_LOC_VARS
ISequentialInStream *inStream,
const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
CFolder &folderItem,
ISequentialOutStream *outStream,
CRecordVector<UInt64> &packSizes,
ICompressProgressInfo *compressProgress)
{
RINOK(EncoderConstr());
if (_mixerCoderSpec == NULL)
{
RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce));
}
_mixerCoderSpec->ReInit();
// _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);
CObjectVector<CInOutTempBuffer> inOutTempBuffers;
CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
int numMethods = _bindInfo.Coders.Size();
int i;
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
{
inOutTempBuffers.Add(CInOutTempBuffer());
inOutTempBuffers.Back().Create();
inOutTempBuffers.Back().InitWriting();
}
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
{
CSequentialOutTempBufferImp *tempBufferSpec =
new CSequentialOutTempBufferImp;
CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
tempBuffers.Add(tempBuffer);
tempBufferSpecs.Add(tempBufferSpec);
}
for (i = 0; i < numMethods; i++)
_mixerCoderSpec->SetCoderInfo(i, NULL, NULL);
if (_bindInfo.InStreams.IsEmpty())
return E_FAIL;
UInt32 mainCoderIndex, mainStreamIndex;
_bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
if (inStreamSize != NULL)
{
CRecordVector<const UInt64 *> sizePointers;
for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
if (i == mainStreamIndex)
sizePointers.Add(inStreamSize);
else
sizePointers.Add(NULL);
_mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);
}
// UInt64 outStreamStartPos;
// RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec =
new CSequentialInStreamSizeCount2;
CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
CSequentialOutStreamSizeCount *outStreamSizeCountSpec =
new CSequentialOutStreamSizeCount;
CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;
inStreamSizeCountSpec->Init(inStream);
outStreamSizeCountSpec->SetStream(outStream);
outStreamSizeCountSpec->Init();
CRecordVector<ISequentialInStream *> inStreamPointers;
CRecordVector<ISequentialOutStream *> outStreamPointers;
inStreamPointers.Add(inStreamSizeCount);
outStreamPointers.Add(outStreamSizeCount);
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
outStreamPointers.Add(tempBuffers[i - 1]);
for (i = 0; i < _codersInfo.Size(); i++)
{
CCoderInfo &encodingInfo = _codersInfo[i];
CMyComPtr<ICryptoResetInitVector> resetInitVector;
_mixerCoderSpec->_coders[i].QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector);
if (resetInitVector != NULL)
{
resetInitVector->ResetInitVector();
}
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
_mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
if (writeCoderProperties != NULL)
{
CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->Init();
writeCoderProperties->WriteCoderProperties(outStream);
size_t size = outStreamSpec->GetSize();
encodingInfo.Properties.SetCapacity(size);
memmove(encodingInfo.Properties, outStreamSpec->GetBuffer(), size);
}
}
UInt32 progressIndex = mainCoderIndex;
for (i = 0; i < _codersInfo.Size(); i++)
{
const CCoderInfo &e = _codersInfo[i];
if ((e.MethodID == k_BCJ || e.MethodID == k_BCJ2) && i + 1 < _codersInfo.Size())
progressIndex = i + 1;
}
_mixerCoderSpec->SetProgressCoderIndex(progressIndex);
RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
&outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods,
folderItem);
packSizes.Add(outStreamSizeCountSpec->GetSize());
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
{
CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
inOutTempBuffer.FlushWrite();
inOutTempBuffer.InitReading();
inOutTempBuffer.WriteToStream(outStream);
packSizes.Add(inOutTempBuffer.GetDataSize());
}
for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
{
int binder = _bindInfo.FindBinderForInStream(
_bindReverseConverter->DestOutToSrcInMap[i]);
UInt64 streamSize;
if (binder < 0)
streamSize = inStreamSizeCountSpec->GetSize();
else
streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
folderItem.UnPackSizes.Add(streamSize);
}
for (i = numMethods - 1; i >= 0; i--)
folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties;
return S_OK;
}
CEncoder::CEncoder(const CCompressionMethodMode &options):
_bindReverseConverter(0),
_constructed(false)
{
if (options.IsEmpty())
throw 1;
_options = options;
_mixerCoderSpec = NULL;
}
HRESULT CEncoder::EncoderConstr()
{
if (_constructed)
return S_OK;
if (_options.Methods.IsEmpty())
{
// it has only password method;
if (!_options.PasswordIsDefined)
throw 1;
if (!_options.Binds.IsEmpty())
throw 1;
NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
CMethodFull method;
method.NumInStreams = 1;
method.NumOutStreams = 1;
coderStreamsInfo.NumInStreams = 1;
coderStreamsInfo.NumOutStreams = 1;
method.Id = k_AES;
_options.Methods.Add(method);
_bindInfo.Coders.Add(coderStreamsInfo);
_bindInfo.InStreams.Add(0);
_bindInfo.OutStreams.Add(0);
}
else
{
UInt32 numInStreams = 0, numOutStreams = 0;
int i;
for (i = 0; i < _options.Methods.Size(); i++)
{
const CMethodFull &methodFull = _options.Methods[i];
NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
coderStreamsInfo.NumInStreams = methodFull.NumOutStreams;
coderStreamsInfo.NumOutStreams = methodFull.NumInStreams;
if (_options.Binds.IsEmpty())
{
if (i < _options.Methods.Size() - 1)
{
NCoderMixer::CBindPair bindPair;
bindPair.InIndex = numInStreams + coderStreamsInfo.NumInStreams;
bindPair.OutIndex = numOutStreams;
_bindInfo.BindPairs.Add(bindPair);
}
else
_bindInfo.OutStreams.Insert(0, numOutStreams);
for (UInt32 j = 1; j < coderStreamsInfo.NumOutStreams; j++)
_bindInfo.OutStreams.Add(numOutStreams + j);
}
numInStreams += coderStreamsInfo.NumInStreams;
numOutStreams += coderStreamsInfo.NumOutStreams;
_bindInfo.Coders.Add(coderStreamsInfo);
}
if (!_options.Binds.IsEmpty())
{
for (i = 0; i < _options.Binds.Size(); i++)
{
NCoderMixer::CBindPair bindPair;
const CBind &bind = _options.Binds[i];
bindPair.InIndex = _bindInfo.GetCoderInStreamIndex(bind.InCoder) + bind.InStream;
bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream;
_bindInfo.BindPairs.Add(bindPair);
}
for (i = 0; i < (int)numOutStreams; i++)
if (_bindInfo.FindBinderForOutStream(i) == -1)
_bindInfo.OutStreams.Add(i);
}
for (i = 0; i < (int)numInStreams; i++)
if (_bindInfo.FindBinderForInStream(i) == -1)
_bindInfo.InStreams.Add(i);
if (_bindInfo.InStreams.IsEmpty())
throw 1; // this is error
// Make main stream first in list
int inIndex = _bindInfo.InStreams[0];
for (;;)
{
UInt32 coderIndex, coderStreamIndex;
_bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex);
UInt32 outIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);
int binder = _bindInfo.FindBinderForOutStream(outIndex);
if (binder >= 0)
{
inIndex = _bindInfo.BindPairs[binder].InIndex;
continue;
}
for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
if (_bindInfo.OutStreams[i] == outIndex)
{
_bindInfo.OutStreams.Delete(i);
_bindInfo.OutStreams.Insert(0, outIndex);
break;
}
break;
}
if (_options.PasswordIsDefined)
{
int numCryptoStreams = _bindInfo.OutStreams.Size();
for (i = 0; i < numCryptoStreams; i++)
{
NCoderMixer::CBindPair bindPair;
bindPair.InIndex = numInStreams + i;
bindPair.OutIndex = _bindInfo.OutStreams[i];
_bindInfo.BindPairs.Add(bindPair);
}
_bindInfo.OutStreams.Clear();
/*
if (numCryptoStreams == 0)
numCryptoStreams = 1;
*/
for (i = 0; i < numCryptoStreams; i++)
{
NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
CMethodFull method;
method.NumInStreams = 1;
method.NumOutStreams = 1;
coderStreamsInfo.NumInStreams = method.NumOutStreams;
coderStreamsInfo.NumOutStreams = method.NumInStreams;
method.Id = k_AES;
_options.Methods.Add(method);
_bindInfo.Coders.Add(coderStreamsInfo);
_bindInfo.OutStreams.Add(numOutStreams + i);
}
}
}
for (int i = _options.Methods.Size() - 1; i >= 0; i--)
{
const CMethodFull &methodFull = _options.Methods[i];
_decompressionMethods.Add(methodFull.Id);
}
_bindReverseConverter = new NCoderMixer::CBindReverseConverter(_bindInfo);
_bindReverseConverter->CreateReverseBindInfo(_decompressBindInfo);
_constructed = true;
return S_OK;
}
CEncoder::~CEncoder()
{
delete _bindReverseConverter;
}
}}

View File

@ -1,55 +0,0 @@
// 7zEncode.h
#ifndef __7Z_ENCODE_H
#define __7Z_ENCODE_H
// #include "../../Common/StreamObjects.h"
#include "7zCompressionMode.h"
#include "../Common/CoderMixer2.h"
#include "../Common/CoderMixer2MT.h"
#ifdef _ST_MODE
#include "../Common/CoderMixer2ST.h"
#endif
#include "7zItem.h"
#include "../../Common/CreateCoder.h"
namespace NArchive {
namespace N7z {
class CEncoder
{
NCoderMixer::CCoderMixer2MT *_mixerCoderSpec;
CMyComPtr<ICompressCoder2> _mixerCoder;
CObjectVector<CCoderInfo> _codersInfo;
CCompressionMethodMode _options;
NCoderMixer::CBindInfo _bindInfo;
NCoderMixer::CBindInfo _decompressBindInfo;
NCoderMixer::CBindReverseConverter *_bindReverseConverter;
CRecordVector<CMethodId> _decompressionMethods;
HRESULT CreateMixerCoder(DECL_EXTERNAL_CODECS_LOC_VARS
const UInt64 *inSizeForReduce);
bool _constructed;
public:
CEncoder(const CCompressionMethodMode &options);
~CEncoder();
HRESULT EncoderConstr();
HRESULT Encode(
DECL_EXTERNAL_CODECS_LOC_VARS
ISequentialInStream *inStream,
const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
CFolder &folderItem,
ISequentialOutStream *outStream,
CRecordVector<UInt64> &packSizes,
ICompressProgressInfo *compressProgress);
};
}}
#endif

View File

@ -1,269 +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
_database.Files.Size();
#endif
if(numItems == 0)
return S_OK;
/*
if(_volumes.Size() != 1)
return E_FAIL;
const CVolume &volume = _volumes.Front();
const CArchiveDatabaseEx &_database = 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 &database = volume.Database;
UInt32 fileIndex = ref.ItemIndex;
#else
const CArchiveDatabaseEx &database = _database;
UInt32 fileIndex = ref2Index;
#endif
CNum folderIndex = database.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 = database.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 = database.FolderStartFileIndex[folderIndex];
for (CNum index = efi.ExtractStatuses.Size();
index <= fileIndex - startIndex; index++)
{
// UInt64 unPackSize = _database.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 &database = volume.Database;
#else
const CArchiveDatabaseEx &database = _database;
#endif
CNum startIndex;
if (efi.FileIndex != kNumNoIndex)
startIndex = efi.FileIndex;
else
startIndex = database.FolderStartFileIndex[efi.FolderIndex];
HRESULT result = folderOutStream->Init(&database,
#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 = database.Folders[folderIndex];
totalFolderPacked = _database.GetFolderFullPackSize(folderIndex);
CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex];
UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0);
#ifndef _NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
if (extractCallback)
extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
#endif
try
{
HRESULT result = decoder.Decode(
EXTERNAL_CODECS_VARS
#ifdef _7Z_VOL
volume.Stream,
#else
_inStream,
#endif
folderStartPackPos,
&database.PackSizes[packStreamIndex],
folderInfo,
outStream,
progress
#ifndef _NO_CRYPTO
, getTextPassword
#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
}
}}

View File

@ -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;
}
}}

View File

@ -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

View File

@ -1,165 +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 &fileInfo = _archiveDatabase->Files[index];
if (!fileInfo.IsAnti && !fileInfo.IsDirectory)
askMode = NArchive::NExtract::NAskMode::kSkip;
}
return _extractCallback->PrepareOperation(askMode);
}
HRESULT CFolderOutStream::WriteEmptyFiles()
{
for(;_currentIndex < _extractStatuses->Size(); _currentIndex++)
{
UInt32 index = _startIndex + _currentIndex;
const CFileItem &fileInfo = _archiveDatabase->Files[index];
if (!fileInfo.IsAnti && !fileInfo.IsDirectory && fileInfo.UnPackSize != 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 &fileInfo = _archiveDatabase->Files[index];
UInt64 fileSize = fileInfo.UnPackSize;
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 (fileInfo.IsFileCRCDefined && _checkCrc)
digestsAreEqual = fileInfo.FileCRC == _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;
}
}}

View File

@ -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

View File

@ -1,793 +0,0 @@
// 7zHandler.cpp
#include "StdAfx.h"
#include "7zHandler.h"
#include "7zProperties.h"
#include "../../../Common/IntToString.h"
#include "../../../Common/ComTry.h"
#include "../../../Windows/Defs.h"
#include "../Common/ItemNameUtils.h"
#ifdef _7Z_VOL
#include "../Common/MultiStream.h"
#endif
#ifdef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
#include "../Common/ParseProperties.h"
#endif
#endif
#ifdef COMPRESS_MT
#include "../../../Windows/System.h"
#endif
using namespace NWindows;
extern UString ConvertMethodIdToString(UInt64 id);
namespace NArchive {
namespace N7z {
CHandler::CHandler()
{
_crcSize = 4;
#ifdef EXTRACT_ONLY
#ifdef COMPRESS_MT
_numThreads = NWindows::NSystem::GetNumberOfProcessors();
#endif
#else
Init();
#endif
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems =
#ifdef _7Z_VOL
_refs.Size();
#else
*numItems = _database.Files.Size();
#endif
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}
};
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
switch(propID)
{
case kpidMethod:
{
UString resString;
CRecordVector<UInt64> ids;
int i;
for (i = 0; i < _database.Folders.Size(); i++)
{
const CFolder &f = _database.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 = _database.IsSolid(); break;
case kpidNumBlocks: prop = (UInt32)_database.Folders.Size(); break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
IMP_IInArchive_ArcProps
#endif
static void MySetFileTime(bool timeDefined, FILETIME unixTime, NWindows::NCOM::CPropVariant &prop)
{
if (timeDefined)
prop = unixTime;
}
#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;
#ifndef _SFX
static inline UInt32 GetUInt32FromMemLE(const Byte *p)
{
return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
}
#endif
bool CHandler::IsEncrypted(UInt32 index2) const
{
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
{
const CFolder &folderInfo = _database.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
NWindows::NCOM::CPropVariant prop;
/*
const CRef2 &ref2 = _refs[index];
if (ref2.Refs.IsEmpty())
return E_FAIL;
const CRef &ref = ref2.Refs.Front();
*/
#ifdef _7Z_VOL
const CRef &ref = _refs[index];
const CVolume &volume = _volumes[ref.VolumeIndex];
const CArchiveDatabaseEx &_database = volume.Database;
UInt32 index2 = ref.ItemIndex;
const CFileItem &item = _database.Files[index2];
#else
const CFileItem &item = _database.Files[index];
UInt32 index2 = index;
#endif
switch(propID)
{
case kpidPath:
{
if (!item.Name.IsEmpty())
prop = NItemName::GetOSName(item.Name);
break;
}
case kpidIsFolder:
prop = item.IsDirectory;
break;
case kpidSize:
{
prop = item.UnPackSize;
// prop = ref2.UnPackSize;
break;
}
case kpidPosition:
{
/*
if (ref2.Refs.Size() > 1)
prop = ref2.StartPos;
else
*/
if (item.IsStartPosDefined)
prop = item.StartPos;
break;
}
case kpidPackedSize:
{
// prop = ref2.PackSize;
{
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
{
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)
prop = _database.GetFolderFullPackSize(folderIndex);
/*
else
prop = (UInt64)0;
*/
}
else
prop = (UInt64)0;
}
break;
}
case kpidLastAccessTime:
MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, prop);
break;
case kpidCreationTime:
MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, prop);
break;
case kpidLastWriteTime:
MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, prop);
break;
case kpidAttributes:
if (item.AreAttributesDefined)
prop = item.Attributes;
break;
case kpidCRC:
if (item.IsFileCRCDefined)
prop = item.FileCRC;
break;
case kpidEncrypted:
{
prop = IsEncrypted(index2);
break;
}
#ifndef _SFX
case kpidMethod:
{
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
{
const CFolder &folderInfo = _database.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.Properties.GetCapacity() >= 5)
{
methodsString += L":";
UInt32 dicSize = GetUInt32FromMemLE(
((const Byte *)coderInfo.Properties + 1));
methodsString += GetStringForSizeValue(dicSize);
}
}
else if (coderInfo.MethodID == k_PPMD)
{
if (coderInfo.Properties.GetCapacity() >= 5)
{
Byte order = *(const Byte *)coderInfo.Properties;
methodsString += L":o";
methodsString += ConvertUInt32ToString(order);
methodsString += L":mem";
UInt32 dicSize = GetUInt32FromMemLE(
((const Byte *)coderInfo.Properties + 1));
methodsString += GetStringForSizeValue(dicSize);
}
}
else if (coderInfo.MethodID == k_AES)
{
if (coderInfo.Properties.GetCapacity() >= 1)
{
methodsString += L":";
const Byte *data = (const Byte *)coderInfo.Properties;
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.Properties.GetCapacity() >= 2)
{
Byte secondByte = *data++;
saltSize += (secondByte >> 4);
ivSize += (secondByte & 0x0F);
}
}
*/
}
}
else
{
if (coderInfo.Properties.GetCapacity() > 0)
{
methodsString += L":[";
for (size_t bi = 0; bi < coderInfo.Properties.GetCapacity(); bi++)
{
if (bi > 5 && bi + 1 < coderInfo.Properties.GetCapacity())
{
methodsString += L"..";
break;
}
else
methodsString += GetHex2(coderInfo.Properties[bi]);
}
methodsString += L"]";
}
}
}
else
{
methodsString += ConvertMethodIdToString(coderInfo.MethodID);
}
}
}
prop = methodsString;
}
}
break;
case kpidBlock:
{
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
prop = (UInt32)folderIndex;
}
break;
case kpidPackedSize0:
case kpidPackedSize1:
case kpidPackedSize2:
case kpidPackedSize3:
case kpidPackedSize4:
{
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
{
const CFolder &folderInfo = _database.Folders[folderIndex];
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
{
prop = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
}
else
prop = (UInt64)0;
}
else
prop = (UInt64)0;
}
break;
#endif
case kpidIsAnti:
prop = item.IsAnti;
break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
#ifdef _7Z_VOL
static const wchar_t *kExt = L"7z";
static const wchar_t *kAfterPart = L".7z";
class CVolumeName
{
bool _first;
UString _unchangedPart;
UString _changedPart;
UString _afterPart;
public:
bool InitName(const UString &name)
{
_first = true;
int dotPos = name.ReverseFind('.');
UString basePart = name;
if (dotPos >= 0)
{
UString ext = name.Mid(dotPos + 1);
if (ext.CompareNoCase(kExt)==0 ||
ext.CompareNoCase(L"EXE") == 0)
{
_afterPart = kAfterPart;
basePart = name.Left(dotPos);
}
}
int numLetters = 1;
bool splitStyle = false;
if (basePart.Right(numLetters) == L"1")
{
while (numLetters < basePart.Length())
{
if (basePart[basePart.Length() - numLetters - 1] != '0')
break;
numLetters++;
}
}
else
return false;
_unchangedPart = basePart.Left(basePart.Length() - numLetters);
_changedPart = basePart.Right(numLetters);
return true;
}
UString GetNextName()
{
UString newName;
// if (_newStyle || !_first)
{
int i;
int numLetters = _changedPart.Length();
for (i = numLetters - 1; i >= 0; i--)
{
wchar_t c = _changedPart[i];
if (c == L'9')
{
c = L'0';
newName = c + newName;
if (i == 0)
newName = UString(L'1') + newName;
continue;
}
c++;
newName = UString(c) + newName;
i--;
for (; i >= 0; i--)
newName = _changedPart[i] + newName;
break;
}
_changedPart = newName;
}
_first = false;
return _unchangedPart + _changedPart + _afterPart;
}
};
#endif
STDMETHODIMP CHandler::Open(IInStream *stream,
const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback)
{
COM_TRY_BEGIN
Close();
#ifndef _SFX
_fileInfoPopIDs.Clear();
#endif
try
{
CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
#ifdef _7Z_VOL
CVolumeName seqName;
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
#endif
#ifndef _NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
if (openArchiveCallback)
{
openArchiveCallbackTemp.QueryInterface(
IID_ICryptoGetTextPassword, &getTextPassword);
}
#endif
#ifdef _7Z_VOL
if (openArchiveCallback)
{
openArchiveCallbackTemp.QueryInterface(IID_IArchiveOpenVolumeCallback, &openVolumeCallback);
}
for (;;)
{
CMyComPtr<IInStream> inStream;
if (!_volumes.IsEmpty())
{
if (!openVolumeCallback)
break;
if(_volumes.Size() == 1)
{
UString baseName;
{
NCOM::CPropVariant prop;
RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
if (prop.vt != VT_BSTR)
break;
baseName = prop.bstrVal;
}
seqName.InitName(baseName);
}
UString fullName = seqName.GetNextName();
HRESULT result = openVolumeCallback->GetStream(fullName, &inStream);
if (result == S_FALSE)
break;
if (result != S_OK)
return result;
if (!stream)
break;
}
else
inStream = stream;
CInArchive archive;
RINOK(archive.Open(inStream, maxCheckStartPosition));
_volumes.Add(CVolume());
CVolume &volume = _volumes.Back();
CArchiveDatabaseEx &database = volume.Database;
volume.Stream = inStream;
volume.StartRef2Index = _refs.Size();
HRESULT result = archive.ReadDatabase(database
#ifndef _NO_CRYPTO
, getTextPassword
#endif
);
if (result != S_OK)
{
_volumes.Clear();
return result;
}
database.Fill();
for(int i = 0; i < database.Files.Size(); i++)
{
CRef refNew;
refNew.VolumeIndex = _volumes.Size() - 1;
refNew.ItemIndex = i;
_refs.Add(refNew);
/*
const CFileItem &file = database.Files[i];
int j;
*/
/*
for (j = _refs.Size() - 1; j >= 0; j--)
{
CRef2 &ref2 = _refs[j];
const CRef &ref = ref2.Refs.Back();
const CVolume &volume2 = _volumes[ref.VolumeIndex];
const CArchiveDatabaseEx &database2 = volume2.Database;
const CFileItem &file2 = database2.Files[ref.ItemIndex];
if (file2.Name.CompareNoCase(file.Name) == 0)
{
if (!file.IsStartPosDefined)
continue;
if (file.StartPos != ref2.StartPos + ref2.UnPackSize)
continue;
ref2.Refs.Add(refNew);
break;
}
}
*/
/*
j = -1;
if (j < 0)
{
CRef2 ref2New;
ref2New.Refs.Add(refNew);
j = _refs.Add(ref2New);
}
CRef2 &ref2 = _refs[j];
ref2.UnPackSize += file.UnPackSize;
ref2.PackSize += database.GetFilePackSize(i);
if (ref2.Refs.Size() == 1 && file.IsStartPosDefined)
ref2.StartPos = file.StartPos;
*/
}
if (database.Files.Size() != 1)
break;
const CFileItem &file = database.Files.Front();
if (!file.IsStartPosDefined)
break;
}
#else
CInArchive archive;
RINOK(archive.Open(stream, maxCheckStartPosition));
HRESULT result = archive.ReadDatabase(
EXTERNAL_CODECS_VARS
_database
#ifndef _NO_CRYPTO
, getTextPassword
#endif
);
RINOK(result);
_database.Fill();
_inStream = stream;
#endif
}
catch(...)
{
Close();
return S_FALSE;
}
// _inStream = stream;
#ifndef _SFX
FillPopIDs();
#endif
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::Close()
{
COM_TRY_BEGIN
#ifdef _7Z_VOL
_volumes.Clear();
_refs.Clear();
#else
_inStream.Release();
_database.Clear();
#endif
return S_OK;
COM_TRY_END
}
#ifdef _7Z_VOL
STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
{
if (index != 0)
return E_INVALIDARG;
*stream = 0;
CMultiStream *streamSpec = new CMultiStream;
CMyComPtr<ISequentialInStream> streamTemp = streamSpec;
UInt64 pos = 0;
const UString *fileName;
for (int i = 0; i < _refs.Size(); i++)
{
const CRef &ref = _refs[i];
const CVolume &volume = _volumes[ref.VolumeIndex];
const CArchiveDatabaseEx &database = volume.Database;
const CFileItem &file = database.Files[ref.ItemIndex];
if (i == 0)
fileName = &file.Name;
else
if (fileName->Compare(file.Name) != 0)
return S_FALSE;
if (!file.IsStartPosDefined)
return S_FALSE;
if (file.StartPos != pos)
return S_FALSE;
CNum folderIndex = database.FileIndexToFolderIndexMap[ref.ItemIndex];
if (folderIndex == kNumNoIndex)
{
if (file.UnPackSize != 0)
return E_FAIL;
continue;
}
if (database.NumUnPackStreamsVector[folderIndex] != 1)
return S_FALSE;
const CFolder &folder = database.Folders[folderIndex];
if (folder.Coders.Size() != 1)
return S_FALSE;
const CCoderInfo &coder = folder.Coders.Front();
if (coder.NumInStreams != 1 || coder.NumOutStreams != 1)
return S_FALSE;
if (coder.MethodID != k_Copy)
return S_FALSE;
pos += file.UnPackSize;
CMultiStream::CSubStreamInfo subStreamInfo;
subStreamInfo.Stream = volume.Stream;
subStreamInfo.Pos = database.GetFolderStreamPos(folderIndex, 0);
subStreamInfo.Size = file.UnPackSize;
streamSpec->Streams.Add(subStreamInfo);
}
streamSpec->Init();
*stream = streamTemp.Detach();
return S_OK;
}
#endif
#ifdef __7Z_SET_PROPERTIES
#ifdef 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
}}

View File

@ -1,146 +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 {
#ifdef _7Z_VOL
struct CRef
{
int VolumeIndex;
int ItemIndex;
};
struct CVolume
{
int StartRef2Index;
CMyComPtr<IInStream> Stream;
CArchiveDatabaseEx Database;
};
#endif
#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_VOL
public IInArchiveGetStream,
#endif
#ifdef __7Z_SET_PROPERTIES
public ISetProperties,
#endif
#ifndef EXTRACT_ONLY
public IOutArchive,
#endif
PUBLIC_ISetCompressCodecsInfo
public CMyUnknownImp
{
public:
MY_QUERYINTERFACE_BEGIN2(IInArchive)
#ifdef _7Z_VOL
MY_QUERYINTERFACE_ENTRY(IInArchiveGetStream)
#endif
#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_VOL
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
#endif
#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:
#ifdef _7Z_VOL
CObjectVector<CVolume> _volumes;
CObjectVector<CRef> _refs;
#else
CMyComPtr<IInStream> _inStream;
NArchive::N7z::CArchiveDatabaseEx _database;
#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
};
}}
#endif

View File

@ -1,464 +0,0 @@
// 7zHandlerOut.cpp
#include "StdAfx.h"
#include "7zHandler.h"
#include "7zOut.h"
#include "7zUpdate.h"
#include "../../../Windows/PropVariant.h"
#include "../../../Common/ComTry.h"
#include "../../../Common/StringToInt.h"
#include "../../IPassword.h"
#include "../../ICoder.h"
#include "../Common/ItemNameUtils.h"
#include "../Common/ParseProperties.h"
using namespace NWindows;
namespace NArchive {
namespace N7z {
static const wchar_t *kLZMAMethodName = L"LZMA";
static const wchar_t *kCopyMethod = L"Copy";
static const wchar_t *kDefaultMethodName = kLZMAMethodName;
static const UInt32 kLzmaAlgorithmX5 = 1;
static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
static const UInt32 kDictionaryForHeaders = 1 << 20;
static const UInt32 kNumFastBytesForHeaders = 273;
static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5;
static inline bool IsCopyMethod(const UString &methodName)
{ return (methodName.CompareNoCase(kCopyMethod) == 0); }
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
{
*type = NFileTimeType::kWindows;
return S_OK;
}
HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode,
IArchiveUpdateCallback *updateCallback)
{
CMyComPtr<ICryptoGetTextPassword2> getTextPassword;
if (!getTextPassword)
{
CMyComPtr<IArchiveUpdateCallback> udateCallback2(updateCallback);
udateCallback2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword);
}
if (getTextPassword)
{
CMyComBSTR password;
Int32 passwordIsDefined;
RINOK(getTextPassword->CryptoGetTextPassword2(
&passwordIsDefined, &password));
methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
if (methodMode.PasswordIsDefined)
methodMode.Password = password;
}
else
methodMode.PasswordIsDefined = false;
return S_OK;
}
HRESULT CHandler::SetCompressionMethod(
CCompressionMethodMode &methodMode,
CCompressionMethodMode &headerMethod)
{
HRESULT res = SetCompressionMethod(methodMode, _methods
#ifdef COMPRESS_MT
, _numThreads
#endif
);
RINOK(res);
methodMode.Binds = _binds;
if (_compressHeaders)
{
// headerMethod.Methods.Add(methodMode.Methods.Back());
CObjectVector<COneMethodInfo> headerMethodInfoVector;
COneMethodInfo oneMethodInfo;
oneMethodInfo.MethodName = kLZMAMethodName;
{
CProp property;
property.Id = NCoderPropID::kMatchFinder;
property.Value = kLzmaMatchFinderForHeaders;
oneMethodInfo.Properties.Add(property);
}
{
CProp property;
property.Id = NCoderPropID::kAlgorithm;
property.Value = kAlgorithmForHeaders;
oneMethodInfo.Properties.Add(property);
}
{
CProp property;
property.Id = NCoderPropID::kNumFastBytes;
property.Value = UInt32(kNumFastBytesForHeaders);
oneMethodInfo.Properties.Add(property);
}
{
CProp property;
property.Id = NCoderPropID::kDictionarySize;
property.Value = UInt32(kDictionaryForHeaders);
oneMethodInfo.Properties.Add(property);
}
headerMethodInfoVector.Add(oneMethodInfo);
HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector
#ifdef COMPRESS_MT
,1
#endif
);
RINOK(res);
}
return S_OK;
}
HRESULT CHandler::SetCompressionMethod(
CCompressionMethodMode &methodMode,
CObjectVector<COneMethodInfo> &methodsInfo
#ifdef COMPRESS_MT
, UInt32 numThreads
#endif
)
{
UInt32 level = _level;
if (methodsInfo.IsEmpty())
{
COneMethodInfo oneMethodInfo;
oneMethodInfo.MethodName = ((level == 0) ? kCopyMethod : kDefaultMethodName);
methodsInfo.Add(oneMethodInfo);
}
bool needSolid = false;
for(int i = 0; i < methodsInfo.Size(); i++)
{
COneMethodInfo &oneMethodInfo = methodsInfo[i];
SetCompressionMethod2(oneMethodInfo
#ifdef COMPRESS_MT
, numThreads
#endif
);
if (!IsCopyMethod(oneMethodInfo.MethodName))
needSolid = true;
CMethodFull methodFull;
if (!FindMethod(
EXTERNAL_CODECS_VARS
oneMethodInfo.MethodName, methodFull.Id, methodFull.NumInStreams, methodFull.NumOutStreams))
return E_INVALIDARG;
methodFull.Properties = oneMethodInfo.Properties;
methodMode.Methods.Add(methodFull);
if (!_numSolidBytesDefined)
{
for (int j = 0; j < methodFull.Properties.Size(); j++)
{
const CProp &prop = methodFull.Properties[j];
if ((prop.Id == NCoderPropID::kDictionarySize ||
prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4)
{
_numSolidBytes = ((UInt64)prop.Value.ulVal) << 7;
const UInt64 kMinSize = (1 << 24);
if (_numSolidBytes < kMinSize)
_numSolidBytes = kMinSize;
_numSolidBytesDefined = true;
break;
}
}
}
}
if (!needSolid && !_numSolidBytesDefined)
{
_numSolidBytesDefined = true;
_numSolidBytes = 0;
}
return S_OK;
}
static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, CArchiveFileTime &filetime, bool &filetimeIsDefined)
{
filetimeIsDefined = false;
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(index, propID, &propVariant));
if (propVariant.vt == VT_FILETIME)
{
filetime = propVariant.filetime;
filetimeIsDefined = true;
}
else if (propVariant.vt != VT_EMPTY)
return E_INVALIDARG;
return S_OK;
}
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback)
{
COM_TRY_BEGIN
const CArchiveDatabaseEx *database = 0;
#ifdef _7Z_VOL
if(_volumes.Size() > 1)
return E_FAIL;
const CVolume *volume = 0;
if (_volumes.Size() == 1)
{
volume = &_volumes.Front();
database = &volume->Database;
}
#else
if (_inStream != 0)
database = &_database;
#endif
// CRecordVector<bool> compressStatuses;
CObjectVector<CUpdateItem> updateItems;
// CRecordVector<UInt32> copyIndices;
// CMyComPtr<IUpdateCallback2> updateCallback2;
// updateCallback->QueryInterface(&updateCallback2);
for(UInt32 i = 0; i < numItems; i++)
{
Int32 newData;
Int32 newProperties;
UInt32 indexInArchive;
if (!updateCallback)
return E_FAIL;
RINOK(updateCallback->GetUpdateItemInfo(i,
&newData, &newProperties, &indexInArchive));
CUpdateItem updateItem;
updateItem.NewProperties = IntToBool(newProperties);
updateItem.NewData = IntToBool(newData);
updateItem.IndexInArchive = indexInArchive;
updateItem.IndexInClient = i;
updateItem.IsAnti = false;
updateItem.Size = 0;
if (updateItem.IndexInArchive != -1)
{
const CFileItem &fileItem = database->Files[updateItem.IndexInArchive];
updateItem.Name = fileItem.Name;
updateItem.IsDirectory = fileItem.IsDirectory;
updateItem.Size = fileItem.UnPackSize;
updateItem.IsAnti = fileItem.IsAnti;
updateItem.CreationTime = fileItem.CreationTime;
updateItem.IsCreationTimeDefined = fileItem.IsCreationTimeDefined;
updateItem.LastWriteTime = fileItem.LastWriteTime;
updateItem.IsLastWriteTimeDefined = fileItem.IsLastWriteTimeDefined;
updateItem.LastAccessTime = fileItem.LastAccessTime;
updateItem.IsLastAccessTimeDefined = fileItem.IsLastAccessTimeDefined;
}
if (updateItem.NewProperties)
{
bool nameIsDefined;
bool folderStatusIsDefined;
{
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant));
if (propVariant.vt == VT_EMPTY)
updateItem.AttributesAreDefined = false;
else if (propVariant.vt != VT_UI4)
return E_INVALIDARG;
else
{
updateItem.Attributes = propVariant.ulVal;
updateItem.AttributesAreDefined = true;
}
}
RINOK(GetTime(updateCallback, i, kpidCreationTime, updateItem.CreationTime, updateItem.IsCreationTimeDefined));
RINOK(GetTime(updateCallback, i, kpidLastWriteTime, updateItem.LastWriteTime , updateItem.IsLastWriteTimeDefined));
RINOK(GetTime(updateCallback, i, kpidLastAccessTime, updateItem.LastAccessTime, updateItem.IsLastAccessTimeDefined));
{
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant));
if (propVariant.vt == VT_EMPTY)
nameIsDefined = false;
else if (propVariant.vt != VT_BSTR)
return E_INVALIDARG;
else
{
updateItem.Name = NItemName::MakeLegalName(propVariant.bstrVal);
nameIsDefined = true;
}
}
{
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant));
if (propVariant.vt == VT_EMPTY)
folderStatusIsDefined = false;
else if (propVariant.vt != VT_BOOL)
return E_INVALIDARG;
else
{
updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE);
folderStatusIsDefined = true;
}
}
{
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(i, kpidIsAnti, &propVariant));
if (propVariant.vt == VT_EMPTY)
updateItem.IsAnti = false;
else if (propVariant.vt != VT_BOOL)
return E_INVALIDARG;
else
updateItem.IsAnti = (propVariant.boolVal != VARIANT_FALSE);
}
if (updateItem.IsAnti)
{
updateItem.AttributesAreDefined = false;
updateItem.IsCreationTimeDefined = false;
updateItem.IsLastWriteTimeDefined = false;
updateItem.IsLastAccessTimeDefined = false;
updateItem.Size = 0;
}
if (!folderStatusIsDefined && updateItem.AttributesAreDefined)
updateItem.SetDirectoryStatusFromAttributes();
}
if (updateItem.NewData)
{
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
if (propVariant.vt != VT_UI8)
return E_INVALIDARG;
updateItem.Size = (UInt64)propVariant.uhVal.QuadPart;
if (updateItem.Size != 0 && updateItem.IsAnti)
return E_INVALIDARG;
}
updateItems.Add(updateItem);
}
CCompressionMethodMode methodMode, headerMethod;
RINOK(SetCompressionMethod(methodMode, headerMethod));
#ifdef COMPRESS_MT
methodMode.NumThreads = _numThreads;
headerMethod.NumThreads = 1;
#endif
RINOK(SetPassword(methodMode, updateCallback));
bool compressMainHeader = _compressHeaders; // check it
if (methodMode.PasswordIsDefined)
{
compressMainHeader = true;
if(_encryptHeaders)
RINOK(SetPassword(headerMethod, updateCallback));
}
if (numItems < 2)
compressMainHeader = false;
CUpdateOptions options;
options.Method = &methodMode;
options.HeaderMethod = (_compressHeaders ||
(methodMode.PasswordIsDefined && _encryptHeaders)) ?
&headerMethod : 0;
options.UseFilters = _level != 0 && _autoFilter;
options.MaxFilter = _level >= 8;
options.HeaderOptions.CompressMainHeader = compressMainHeader;
options.HeaderOptions.WriteModified = WriteModified;
options.HeaderOptions.WriteCreated = WriteCreated;
options.HeaderOptions.WriteAccessed = WriteAccessed;
options.NumSolidFiles = _numSolidFiles;
options.NumSolidBytes = _numSolidBytes;
options.SolidExtension = _solidExtension;
options.RemoveSfxBlock = _removeSfxBlock;
options.VolumeMode = _volumeMode;
return Update(
EXTERNAL_CODECS_VARS
#ifdef _7Z_VOL
volume ? volume->Stream: 0,
volume ? database: 0,
#else
_inStream,
database,
#endif
updateItems, outStream, updateCallback, options);
COM_TRY_END
}
static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream)
{
stream = 0;
int index = ParseStringToUInt32(srcString, coder);
if (index == 0)
return E_INVALIDARG;
srcString.Delete(0, index);
if (srcString[0] == 'S')
{
srcString.Delete(0);
int index = ParseStringToUInt32(srcString, stream);
if (index == 0)
return E_INVALIDARG;
srcString.Delete(0, index);
}
return S_OK;
}
static HRESULT GetBindInfo(UString &srcString, CBind &bind)
{
RINOK(GetBindInfoPart(srcString, bind.OutCoder, bind.OutStream));
if (srcString[0] != ':')
return E_INVALIDARG;
srcString.Delete(0);
RINOK(GetBindInfoPart(srcString, bind.InCoder, bind.InStream));
if (!srcString.IsEmpty())
return E_INVALIDARG;
return S_OK;
}
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
{
COM_TRY_BEGIN
_binds.Clear();
BeforeSetProperty();
for (int i = 0; i < numProperties; i++)
{
UString name = names[i];
name.MakeUpper();
if (name.IsEmpty())
return E_INVALIDARG;
const PROPVARIANT &value = values[i];
if (name[0] == 'B')
{
name.Delete(0);
CBind bind;
RINOK(GetBindInfo(name, bind));
_binds.Add(bind);
continue;
}
RINOK(SetProperty(name, value));
}
return S_OK;
COM_TRY_END
}
}}

View File

@ -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;
}}

View File

@ -1,96 +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,
kCreationTime,
kLastAccessTime,
kLastWriteTime,
kWinAttributes,
kComment,
kEncodedHeader,
kStartPos
};
}
}}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,235 +0,0 @@
// 7zIn.h
#ifndef __7Z_IN_H
#define __7Z_IN_H
#include "../../../Common/MyCom.h"
#include "../../IStream.h"
#include "../../IPassword.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;
void Clear()
{
CArchiveDatabase::Clear();
ArchiveInfo.Clear();
PackStreamStartPositions.Clear();
FolderStartPackStreamIndex.Clear();
FolderStartFileIndex.Clear();
FileIndexToFolderIndexMap.Clear();
}
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;
size_t _pos;
public:
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];
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,
CRecordVector<bool> &digestsDefined, CRecordVector<UInt32> &digests);
void ReadPackInfo(
UInt64 &dataOffset,
CRecordVector<UInt64> &packSizes,
CRecordVector<bool> &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,
CRecordVector<bool> &digestsDefined,
CRecordVector<UInt32> &digests);
void ReadStreamsInfo(
const CObjectVector<CByteBuffer> *dataVector,
UInt64 &dataOffset,
CRecordVector<UInt64> &packSizes,
CRecordVector<bool> &packCRCsDefined,
CRecordVector<UInt32> &packCRCs,
CObjectVector<CFolder> &folders,
CRecordVector<CNum> &numUnPackStreamsInFolders,
CRecordVector<UInt64> &unPackSizes,
CRecordVector<bool> &digestsDefined,
CRecordVector<UInt32> &digests);
void ReadBoolVector(int numItems, CBoolVector &v);
void ReadBoolVector2(int numItems, CBoolVector &v);
void ReadTime(const CObjectVector<CByteBuffer> &dataVector,
CObjectVector<CFileItem> &files, UInt32 type);
HRESULT ReadAndDecodePackedStreams(
DECL_EXTERNAL_CODECS_LOC_VARS
UInt64 baseOffset, UInt64 &dataOffset,
CObjectVector<CByteBuffer> &dataVector
#ifndef _NO_CRYPTO
, ICryptoGetTextPassword *getTextPassword
#endif
);
HRESULT ReadHeader(
DECL_EXTERNAL_CODECS_LOC_VARS
CArchiveDatabaseEx &database
#ifndef _NO_CRYPTO
,ICryptoGetTextPassword *getTextPassword
#endif
);
HRESULT ReadDatabase2(
DECL_EXTERNAL_CODECS_LOC_VARS
CArchiveDatabaseEx &database
#ifndef _NO_CRYPTO
,ICryptoGetTextPassword *getTextPassword
#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 &database
#ifndef _NO_CRYPTO
,ICryptoGetTextPassword *getTextPassword
#endif
);
};
}}
#endif

View File

@ -1,184 +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 Properties;
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;
}
};
typedef FILETIME CArchiveFileTime;
class CFileItem
{
public:
CArchiveFileTime CreationTime;
CArchiveFileTime LastWriteTime;
CArchiveFileTime LastAccessTime;
UInt64 UnPackSize;
UInt64 StartPos;
UInt32 Attributes;
UInt32 FileCRC;
UString Name;
bool HasStream; // Test it !!! it means that there is
// stream in some folder. It can be empty stream
bool IsDirectory;
bool IsAnti;
bool IsFileCRCDefined;
bool AreAttributesDefined;
bool IsCreationTimeDefined;
bool IsLastWriteTimeDefined;
bool IsLastAccessTimeDefined;
bool IsStartPosDefined;
/*
const bool HasStream() const {
return !IsDirectory && !IsAnti && UnPackSize != 0; }
*/
CFileItem():
HasStream(true),
IsDirectory(false),
IsAnti(false),
IsFileCRCDefined(false),
AreAttributesDefined(false),
IsCreationTimeDefined(false),
IsLastWriteTimeDefined(false),
IsLastAccessTimeDefined(false),
IsStartPosDefined(false)
{}
void SetAttributes(UInt32 attributes)
{
AreAttributesDefined = true;
Attributes = attributes;
}
void SetCreationTime(const CArchiveFileTime &creationTime)
{
IsCreationTimeDefined = true;
CreationTime = creationTime;
}
void SetLastWriteTime(const CArchiveFileTime &lastWriteTime)
{
IsLastWriteTimeDefined = true;
LastWriteTime = lastWriteTime;
}
void SetLastAccessTime(const CArchiveFileTime &lastAccessTime)
{
IsLastAccessTimeDefined = true;
LastAccessTime = lastAccessTime;
}
};
struct CArchiveDatabase
{
CRecordVector<UInt64> PackSizes;
CRecordVector<bool> PackCRCsDefined;
CRecordVector<UInt32> PackCRCs;
CObjectVector<CFolder> Folders;
CRecordVector<CNum> NumUnPackStreamsVector;
CObjectVector<CFileItem> Files;
void Clear()
{
PackSizes.Clear();
PackCRCsDefined.Clear();
PackCRCs.Clear();
Folders.Clear();
NumUnPackStreamsVector.Clear();
Files.Clear();
}
bool IsEmpty() const
{
return (PackSizes.IsEmpty() &&
PackCRCsDefined.IsEmpty() &&
PackCRCs.IsEmpty() &&
Folders.IsEmpty() &&
NumUnPackStreamsVector.IsEmpty() &&
Files.IsEmpty());
}
bool IsSolid() const
{
for (int i = 0; i < NumUnPackStreamsVector.Size(); i++)
if (NumUnPackStreamsVector[i] > 1)
return true;
return false;
}
};
}}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,193 +0,0 @@
// 7z/Out.h
#ifndef __7Z_OUT_H
#define __7Z_OUT_H
#include "7zHeader.h"
#include "7zItem.h"
#include "7zCompressionMode.h"
#include "7zEncode.h"
#include "../../Common/OutBuffer.h"
#include "../../../Common/DynamicBuffer.h"
namespace NArchive {
namespace N7z {
class CWriteBufferLoc
{
Byte *_data;
size_t _size;
size_t _pos;
public:
CWriteBufferLoc(): _size(0), _pos(0) {}
void Init(Byte *data, size_t size)
{
_pos = 0;
_data = data;
_size = size;
}
HRESULT Write(const void *data, size_t size)
{
if (_pos + size > _size)
return E_FAIL;
memmove(_data + _pos, data, size);
_pos += size;
return S_OK;
}
};
class CWriteDynamicBuffer
{
CByteDynamicBuffer _buffer;
size_t _pos;
public:
CWriteDynamicBuffer(): _pos(0) {}
void Init()
{
_pos = 0;
}
void Write(const void *data, size_t size)
{
if (_pos + size > _buffer.GetCapacity())
_buffer.EnsureCapacity(_pos + size);
memmove(((Byte *)_buffer) +_pos, data, size);
_pos += size;
}
operator Byte *() { return (Byte *)_buffer; };
operator const Byte *() const { return (const Byte *)_buffer; };
size_t GetSize() const { return _pos; }
};
struct CHeaderOptions
{
// bool UseAdditionalHeaderStreams;
bool CompressMainHeader;
bool WriteModified;
bool WriteCreated;
bool WriteAccessed;
CHeaderOptions():
// UseAdditionalHeaderStreams(false),
CompressMainHeader(true),
WriteModified(true),
WriteCreated(false),
WriteAccessed(false) {}
};
class COutArchive
{
UInt64 _prefixHeaderPos;
HRESULT WriteDirect(const void *data, UInt32 size);
HRESULT WriteDirectByte(Byte b) { return WriteDirect(&b, 1); }
HRESULT WriteDirectUInt32(UInt32 value);
HRESULT WriteDirectUInt64(UInt64 value);
HRESULT WriteBytes(const void *data, size_t size);
HRESULT WriteBytes(const CByteBuffer &data);
HRESULT WriteByte(Byte b);
HRESULT WriteUInt32(UInt32 value);
HRESULT WriteNumber(UInt64 value);
HRESULT WriteID(UInt64 value) { return WriteNumber(value); }
HRESULT WriteFolder(const CFolder &folder);
HRESULT WriteFileHeader(const CFileItem &itemInfo);
HRESULT WriteBoolVector(const CBoolVector &boolVector);
HRESULT WriteHashDigests(
const CRecordVector<bool> &digestsDefined,
const CRecordVector<UInt32> &hashDigests);
HRESULT WritePackInfo(
UInt64 dataOffset,
const CRecordVector<UInt64> &packSizes,
const CRecordVector<bool> &packCRCsDefined,
const CRecordVector<UInt32> &packCRCs);
HRESULT WriteUnPackInfo(const CObjectVector<CFolder> &folders);
HRESULT WriteSubStreamsInfo(
const CObjectVector<CFolder> &folders,
const CRecordVector<CNum> &numUnPackStreamsInFolders,
const CRecordVector<UInt64> &unPackSizes,
const CRecordVector<bool> &digestsDefined,
const CRecordVector<UInt32> &hashDigests);
/*
HRESULT WriteStreamsInfo(
UInt64 dataOffset,
const CRecordVector<UInt64> &packSizes,
const CRecordVector<bool> &packCRCsDefined,
const CRecordVector<UInt32> &packCRCs,
bool externalFolders,
UInt64 externalFoldersStreamIndex,
const CObjectVector<CFolder> &folders,
const CRecordVector<CNum> &numUnPackStreamsInFolders,
const CRecordVector<UInt64> &unPackSizes,
const CRecordVector<bool> &digestsDefined,
const CRecordVector<UInt32> &hashDigests);
*/
HRESULT WriteTime(const CObjectVector<CFileItem> &files, Byte type);
HRESULT EncodeStream(
DECL_EXTERNAL_CODECS_LOC_VARS
CEncoder &encoder, const Byte *data, size_t dataSize,
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
HRESULT EncodeStream(
DECL_EXTERNAL_CODECS_LOC_VARS
CEncoder &encoder, const CByteBuffer &data,
CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders);
HRESULT WriteHeader(
const CArchiveDatabase &database,
const CHeaderOptions &headerOptions,
UInt64 &headerOffset);
bool _mainMode;
bool _dynamicMode;
bool _countMode;
size_t _countSize;
COutBuffer _outByte;
CWriteBufferLoc _outByte2;
CWriteDynamicBuffer _dynamicBuffer;
UInt32 _crc;
#ifdef _7Z_VOL
bool _endMarker;
#endif
HRESULT WriteSignature();
#ifdef _7Z_VOL
HRESULT WriteFinishSignature();
#endif
HRESULT WriteStartHeader(const CStartHeader &h);
#ifdef _7Z_VOL
HRESULT WriteFinishHeader(const CFinishHeader &h);
#endif
CMyComPtr<IOutStream> Stream;
public:
COutArchive() { _outByte.Create(1 << 16); }
CMyComPtr<ISequentialOutStream> SeqStream;
HRESULT Create(ISequentialOutStream *stream, bool endMarker);
void Close();
HRESULT SkeepPrefixArchiveHeader();
HRESULT WriteDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
const CArchiveDatabase &database,
const CCompressionMethodMode *options,
const CHeaderOptions &headerOptions);
#ifdef _7Z_VOL
static UInt32 GetVolHeadersSize(UInt64 dataSize, int nameLength = 0, bool props = false);
static UInt64 GetVolPureSize(UInt64 volSize, int nameLength = 0, bool props = false);
#endif
};
}}
#endif

View File

@ -1,162 +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, kpidPackedSize, 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::kCreationTime, NULL, kpidCreationTime, VT_FILETIME},
{ NID::kLastWriteTime, NULL, kpidLastWriteTime, VT_FILETIME},
{ NID::kLastAccessTime, NULL, kpidLastAccessTime, VT_FILETIME},
{ NID::kWinAttributes, NULL, kpidAttributes, VT_UI4},
{ NID::kStartPos, NULL, kpidPosition, VT_UI4},
{ NID::kCRC, NULL, kpidCRC, VT_UI4},
{ NID::kAnti, NULL, kpidIsAnti, VT_BOOL},
// { 97, NULL, kpidSolid, VT_BOOL},
#ifndef _SFX
{ 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 &_database = volume.Database;
#endif
CRecordVector<UInt64> fileInfoPopIDs = _database.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::kCreationTime);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastWriteTime);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kLastAccessTime);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kWinAttributes);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kCRC);
CopyOneItem(fileInfoPopIDs, _fileInfoPopIDs, NID::kComment);
_fileInfoPopIDs += fileInfoPopIDs;
#ifndef _SFX
_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::kLastWriteTime);
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;
}
}}

View File

@ -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

View File

@ -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' + 1 , 'z', 0xBC, 0xAF, 0x27, 0x1C}, 6, false, CreateArc, CreateArcOut };
REGISTER_ARC_DEC_SIG(7z)

View File

@ -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);
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -1,80 +0,0 @@
// 7zUpdate.h
#ifndef __7Z_UPDATE_H
#define __7Z_UPDATE_H
#include "7zIn.h"
#include "7zOut.h"
#include "7zCompressionMode.h"
#include "../IArchive.h"
namespace NArchive {
namespace N7z {
struct CUpdateItem
{
bool NewData;
bool NewProperties;
int IndexInArchive;
int IndexInClient;
UInt32 Attributes;
FILETIME CreationTime;
FILETIME LastWriteTime;
FILETIME LastAccessTime;
UInt64 Size;
UString Name;
bool IsAnti;
bool IsDirectory;
bool IsCreationTimeDefined;
bool IsLastWriteTimeDefined;
bool IsLastAccessTimeDefined;
bool AttributesAreDefined;
bool HasStream() const
{ return !IsDirectory && !IsAnti && Size != 0; }
CUpdateItem():
IsAnti(false),
AttributesAreDefined(false),
IsCreationTimeDefined(false),
IsLastWriteTimeDefined(false),
IsLastAccessTimeDefined(false)
{}
void SetDirectoryStatusFromAttributes()
{ IsDirectory = ((Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0); };
int GetExtensionPos() const;
UString GetExtension() const;
};
struct CUpdateOptions
{
const CCompressionMethodMode *Method;
const CCompressionMethodMode *HeaderMethod;
bool UseFilters;
bool MaxFilter;
CHeaderOptions HeaderOptions;
UInt64 NumSolidFiles;
UInt64 NumSolidBytes;
bool SolidExtension;
bool RemoveSfxBlock;
bool VolumeMode;
};
HRESULT Update(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
const CArchiveDatabaseEx *database,
const CObjectVector<CUpdateItem> &updateItems,
ISequentialOutStream *seqOutStream,
IArchiveUpdateCallback *updateCallback,
const CUpdateOptions &options);
}}
#endif

View File

@ -1,3 +0,0 @@
// StdAfx.cpp
#include "StdAfx.h"

View File

@ -1,9 +0,0 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/MyWindows.h"
#include "../../../Common/NewHandler.h"
#endif

View File

@ -1,6 +0,0 @@
EXPORTS
CreateObject PRIVATE
GetHandlerProperty PRIVATE
GetNumberOfFormats PRIVATE
GetHandlerProperty2 PRIVATE
CreateObject PRIVATE

View File

@ -1,9 +0,0 @@
EXPORTS
CreateObject PRIVATE
GetHandlerProperty PRIVATE
GetNumberOfFormats PRIVATE
GetHandlerProperty2 PRIVATE
CreateObject PRIVATE
GetNumberOfMethods PRIVATE
GetMethodProperty PRIVATE
SetLargePageMode PRIVATE

View File

@ -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 (UInt32 i = 0; i < g_NumArcs; i++)
if (g_Arcs[i]->ClassId == id)
return 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;
}

View File

@ -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);
}
}

Some files were not shown because too many files have changed in this diff Show More