SVN: Applied proper properties to all files, mainly to get native end of lines.
git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@975 a31d4220-a93d-0410-bf67-fe4944624d44
This commit is contained in:
parent
35f5665525
commit
dee05ff978
406
fex/7z_C/7z.h
406
fex/7z_C/7z.h
|
@ -1,203 +1,203 @@
|
||||||
/* 7z.h -- 7z interface
|
/* 7z.h -- 7z interface
|
||||||
2010-03-11 : Igor Pavlov : Public domain */
|
2010-03-11 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_H
|
#ifndef __7Z_H
|
||||||
#define __7Z_H
|
#define __7Z_H
|
||||||
|
|
||||||
#include "7zBuf.h"
|
#include "7zBuf.h"
|
||||||
|
|
||||||
EXTERN_C_BEGIN
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
#define k7zStartHeaderSize 0x20
|
#define k7zStartHeaderSize 0x20
|
||||||
#define k7zSignatureSize 6
|
#define k7zSignatureSize 6
|
||||||
extern Byte k7zSignature[k7zSignatureSize];
|
extern Byte k7zSignature[k7zSignatureSize];
|
||||||
#define k7zMajorVersion 0
|
#define k7zMajorVersion 0
|
||||||
|
|
||||||
enum EIdEnum
|
enum EIdEnum
|
||||||
{
|
{
|
||||||
k7zIdEnd,
|
k7zIdEnd,
|
||||||
k7zIdHeader,
|
k7zIdHeader,
|
||||||
k7zIdArchiveProperties,
|
k7zIdArchiveProperties,
|
||||||
k7zIdAdditionalStreamsInfo,
|
k7zIdAdditionalStreamsInfo,
|
||||||
k7zIdMainStreamsInfo,
|
k7zIdMainStreamsInfo,
|
||||||
k7zIdFilesInfo,
|
k7zIdFilesInfo,
|
||||||
k7zIdPackInfo,
|
k7zIdPackInfo,
|
||||||
k7zIdUnpackInfo,
|
k7zIdUnpackInfo,
|
||||||
k7zIdSubStreamsInfo,
|
k7zIdSubStreamsInfo,
|
||||||
k7zIdSize,
|
k7zIdSize,
|
||||||
k7zIdCRC,
|
k7zIdCRC,
|
||||||
k7zIdFolder,
|
k7zIdFolder,
|
||||||
k7zIdCodersUnpackSize,
|
k7zIdCodersUnpackSize,
|
||||||
k7zIdNumUnpackStream,
|
k7zIdNumUnpackStream,
|
||||||
k7zIdEmptyStream,
|
k7zIdEmptyStream,
|
||||||
k7zIdEmptyFile,
|
k7zIdEmptyFile,
|
||||||
k7zIdAnti,
|
k7zIdAnti,
|
||||||
k7zIdName,
|
k7zIdName,
|
||||||
k7zIdCTime,
|
k7zIdCTime,
|
||||||
k7zIdATime,
|
k7zIdATime,
|
||||||
k7zIdMTime,
|
k7zIdMTime,
|
||||||
k7zIdWinAttributes,
|
k7zIdWinAttributes,
|
||||||
k7zIdComment,
|
k7zIdComment,
|
||||||
k7zIdEncodedHeader,
|
k7zIdEncodedHeader,
|
||||||
k7zIdStartPos,
|
k7zIdStartPos,
|
||||||
k7zIdDummy
|
k7zIdDummy
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UInt32 NumInStreams;
|
UInt32 NumInStreams;
|
||||||
UInt32 NumOutStreams;
|
UInt32 NumOutStreams;
|
||||||
UInt64 MethodID;
|
UInt64 MethodID;
|
||||||
CBuf Props;
|
CBuf Props;
|
||||||
} CSzCoderInfo;
|
} CSzCoderInfo;
|
||||||
|
|
||||||
void SzCoderInfo_Init(CSzCoderInfo *p);
|
void SzCoderInfo_Init(CSzCoderInfo *p);
|
||||||
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
|
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UInt32 InIndex;
|
UInt32 InIndex;
|
||||||
UInt32 OutIndex;
|
UInt32 OutIndex;
|
||||||
} CSzBindPair;
|
} CSzBindPair;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CSzCoderInfo *Coders;
|
CSzCoderInfo *Coders;
|
||||||
CSzBindPair *BindPairs;
|
CSzBindPair *BindPairs;
|
||||||
UInt32 *PackStreams;
|
UInt32 *PackStreams;
|
||||||
UInt64 *UnpackSizes;
|
UInt64 *UnpackSizes;
|
||||||
UInt32 NumCoders;
|
UInt32 NumCoders;
|
||||||
UInt32 NumBindPairs;
|
UInt32 NumBindPairs;
|
||||||
UInt32 NumPackStreams;
|
UInt32 NumPackStreams;
|
||||||
int UnpackCRCDefined;
|
int UnpackCRCDefined;
|
||||||
UInt32 UnpackCRC;
|
UInt32 UnpackCRC;
|
||||||
|
|
||||||
UInt32 NumUnpackStreams;
|
UInt32 NumUnpackStreams;
|
||||||
} CSzFolder;
|
} CSzFolder;
|
||||||
|
|
||||||
void SzFolder_Init(CSzFolder *p);
|
void SzFolder_Init(CSzFolder *p);
|
||||||
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
||||||
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
|
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
|
||||||
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
|
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
|
||||||
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
||||||
|
|
||||||
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
|
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
|
||||||
ILookInStream *stream, UInt64 startPos,
|
ILookInStream *stream, UInt64 startPos,
|
||||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
|
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UInt32 Low;
|
UInt32 Low;
|
||||||
UInt32 High;
|
UInt32 High;
|
||||||
} CNtfsFileTime;
|
} CNtfsFileTime;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CNtfsFileTime MTime;
|
CNtfsFileTime MTime;
|
||||||
UInt64 Size;
|
UInt64 Size;
|
||||||
UInt32 Crc;
|
UInt32 Crc;
|
||||||
UInt32 Attrib;
|
UInt32 Attrib;
|
||||||
Byte HasStream;
|
Byte HasStream;
|
||||||
Byte IsDir;
|
Byte IsDir;
|
||||||
Byte IsAnti;
|
Byte IsAnti;
|
||||||
Byte CrcDefined;
|
Byte CrcDefined;
|
||||||
Byte MTimeDefined;
|
Byte MTimeDefined;
|
||||||
Byte AttribDefined;
|
Byte AttribDefined;
|
||||||
} CSzFileItem;
|
} CSzFileItem;
|
||||||
|
|
||||||
void SzFile_Init(CSzFileItem *p);
|
void SzFile_Init(CSzFileItem *p);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UInt64 *PackSizes;
|
UInt64 *PackSizes;
|
||||||
Byte *PackCRCsDefined;
|
Byte *PackCRCsDefined;
|
||||||
UInt32 *PackCRCs;
|
UInt32 *PackCRCs;
|
||||||
CSzFolder *Folders;
|
CSzFolder *Folders;
|
||||||
CSzFileItem *Files;
|
CSzFileItem *Files;
|
||||||
UInt32 NumPackStreams;
|
UInt32 NumPackStreams;
|
||||||
UInt32 NumFolders;
|
UInt32 NumFolders;
|
||||||
UInt32 NumFiles;
|
UInt32 NumFiles;
|
||||||
} CSzAr;
|
} CSzAr;
|
||||||
|
|
||||||
void SzAr_Init(CSzAr *p);
|
void SzAr_Init(CSzAr *p);
|
||||||
void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
|
void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SzExtract extracts file from archive
|
SzExtract extracts file from archive
|
||||||
|
|
||||||
*outBuffer must be 0 before first call for each new archive.
|
*outBuffer must be 0 before first call for each new archive.
|
||||||
|
|
||||||
Extracting cache:
|
Extracting cache:
|
||||||
If you need to decompress more than one file, you can send
|
If you need to decompress more than one file, you can send
|
||||||
these values from previous call:
|
these values from previous call:
|
||||||
*blockIndex,
|
*blockIndex,
|
||||||
*outBuffer,
|
*outBuffer,
|
||||||
*outBufferSize
|
*outBufferSize
|
||||||
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
||||||
it will increase decompression speed.
|
it will increase decompression speed.
|
||||||
|
|
||||||
If you use external function, you can declare these 3 cache variables
|
If you use external function, you can declare these 3 cache variables
|
||||||
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
||||||
|
|
||||||
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CSzAr db;
|
CSzAr db;
|
||||||
|
|
||||||
UInt64 startPosAfterHeader;
|
UInt64 startPosAfterHeader;
|
||||||
UInt64 dataPos;
|
UInt64 dataPos;
|
||||||
|
|
||||||
UInt32 *FolderStartPackStreamIndex;
|
UInt32 *FolderStartPackStreamIndex;
|
||||||
UInt64 *PackStreamStartPositions;
|
UInt64 *PackStreamStartPositions;
|
||||||
UInt32 *FolderStartFileIndex;
|
UInt32 *FolderStartFileIndex;
|
||||||
UInt32 *FileIndexToFolderIndexMap;
|
UInt32 *FileIndexToFolderIndexMap;
|
||||||
|
|
||||||
size_t *FileNameOffsets; /* in 2-byte steps */
|
size_t *FileNameOffsets; /* in 2-byte steps */
|
||||||
CBuf FileNames; /* UTF-16-LE */
|
CBuf FileNames; /* UTF-16-LE */
|
||||||
} CSzArEx;
|
} CSzArEx;
|
||||||
|
|
||||||
void SzArEx_Init(CSzArEx *p);
|
void SzArEx_Init(CSzArEx *p);
|
||||||
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
|
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
|
||||||
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
|
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
|
||||||
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
|
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if dest == NULL, the return value specifies the required size of the buffer,
|
if dest == NULL, the return value specifies the required size of the buffer,
|
||||||
in 16-bit characters, including the null-terminating character.
|
in 16-bit characters, including the null-terminating character.
|
||||||
if dest != NULL, the return value specifies the number of 16-bit characters that
|
if dest != NULL, the return value specifies the number of 16-bit characters that
|
||||||
are written to the dest, including the null-terminating character. */
|
are written to the dest, including the null-terminating character. */
|
||||||
|
|
||||||
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
|
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
|
||||||
|
|
||||||
SRes SzArEx_Extract(
|
SRes SzArEx_Extract(
|
||||||
const CSzArEx *db,
|
const CSzArEx *db,
|
||||||
ILookInStream *inStream,
|
ILookInStream *inStream,
|
||||||
UInt32 fileIndex, /* index of file */
|
UInt32 fileIndex, /* index of file */
|
||||||
UInt32 *blockIndex, /* index of solid block */
|
UInt32 *blockIndex, /* index of solid block */
|
||||||
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
||||||
size_t *outBufferSize, /* buffer size for output buffer */
|
size_t *outBufferSize, /* buffer size for output buffer */
|
||||||
size_t *offset, /* offset of stream for required file in *outBuffer */
|
size_t *offset, /* offset of stream for required file in *outBuffer */
|
||||||
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
||||||
ISzAlloc *allocMain,
|
ISzAlloc *allocMain,
|
||||||
ISzAlloc *allocTemp);
|
ISzAlloc *allocTemp);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SzArEx_Open Errors:
|
SzArEx_Open Errors:
|
||||||
SZ_ERROR_NO_ARCHIVE
|
SZ_ERROR_NO_ARCHIVE
|
||||||
SZ_ERROR_ARCHIVE
|
SZ_ERROR_ARCHIVE
|
||||||
SZ_ERROR_UNSUPPORTED
|
SZ_ERROR_UNSUPPORTED
|
||||||
SZ_ERROR_MEM
|
SZ_ERROR_MEM
|
||||||
SZ_ERROR_CRC
|
SZ_ERROR_CRC
|
||||||
SZ_ERROR_INPUT_EOF
|
SZ_ERROR_INPUT_EOF
|
||||||
SZ_ERROR_FAIL
|
SZ_ERROR_FAIL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
|
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
/* 7zAlloc.h -- Allocation functions
|
/* 7zAlloc.h -- Allocation functions
|
||||||
2010-10-29 : Igor Pavlov : Public domain */
|
2010-10-29 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_ALLOC_H
|
#ifndef __7Z_ALLOC_H
|
||||||
#define __7Z_ALLOC_H
|
#define __7Z_ALLOC_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
void *SzAlloc(void *p, size_t size);
|
void *SzAlloc(void *p, size_t size);
|
||||||
void SzFree(void *p, void *address);
|
void SzFree(void *p, void *address);
|
||||||
|
|
||||||
void *SzAllocTemp(void *p, size_t size);
|
void *SzAllocTemp(void *p, size_t size);
|
||||||
void SzFreeTemp(void *p, void *address);
|
void SzFreeTemp(void *p, void *address);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
/* 7zBuf.c -- Byte Buffer
|
/* 7zBuf.c -- Byte Buffer
|
||||||
2008-03-28
|
2008-03-28
|
||||||
Igor Pavlov
|
Igor Pavlov
|
||||||
Public domain */
|
Public domain */
|
||||||
|
|
||||||
#include "7zBuf.h"
|
#include "7zBuf.h"
|
||||||
|
|
||||||
void Buf_Init(CBuf *p)
|
void Buf_Init(CBuf *p)
|
||||||
{
|
{
|
||||||
p->data = 0;
|
p->data = 0;
|
||||||
p->size = 0;
|
p->size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
|
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
p->size = 0;
|
p->size = 0;
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
p->data = 0;
|
p->data = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
p->data = (Byte *)alloc->Alloc(alloc, size);
|
p->data = (Byte *)alloc->Alloc(alloc, size);
|
||||||
if (p->data != 0)
|
if (p->data != 0)
|
||||||
{
|
{
|
||||||
p->size = size;
|
p->size = size;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buf_Free(CBuf *p, ISzAlloc *alloc)
|
void Buf_Free(CBuf *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->data);
|
alloc->Free(alloc, p->data);
|
||||||
p->data = 0;
|
p->data = 0;
|
||||||
p->size = 0;
|
p->size = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +1,39 @@
|
||||||
/* 7zBuf.h -- Byte Buffer
|
/* 7zBuf.h -- Byte Buffer
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
2009-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_BUF_H
|
#ifndef __7Z_BUF_H
|
||||||
#define __7Z_BUF_H
|
#define __7Z_BUF_H
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
Byte *data;
|
Byte *data;
|
||||||
size_t size;
|
size_t size;
|
||||||
} CBuf;
|
} CBuf;
|
||||||
|
|
||||||
void Buf_Init(CBuf *p);
|
void Buf_Init(CBuf *p);
|
||||||
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
|
int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
|
||||||
void Buf_Free(CBuf *p, ISzAlloc *alloc);
|
void Buf_Free(CBuf *p, ISzAlloc *alloc);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
Byte *data;
|
Byte *data;
|
||||||
size_t size;
|
size_t size;
|
||||||
size_t pos;
|
size_t pos;
|
||||||
} CDynBuf;
|
} CDynBuf;
|
||||||
|
|
||||||
void DynBuf_Construct(CDynBuf *p);
|
void DynBuf_Construct(CDynBuf *p);
|
||||||
void DynBuf_SeekToBeg(CDynBuf *p);
|
void DynBuf_SeekToBeg(CDynBuf *p);
|
||||||
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);
|
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);
|
||||||
void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);
|
void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
148
fex/7z_C/7zCrc.c
148
fex/7z_C/7zCrc.c
|
@ -1,74 +1,74 @@
|
||||||
/* 7zCrc.c -- CRC32 calculation
|
/* 7zCrc.c -- CRC32 calculation
|
||||||
2009-11-23 : Igor Pavlov : Public domain */
|
2009-11-23 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "7zCrc.h"
|
#include "7zCrc.h"
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
|
||||||
#define kCrcPoly 0xEDB88320
|
#define kCrcPoly 0xEDB88320
|
||||||
|
|
||||||
#ifdef MY_CPU_LE
|
#ifdef MY_CPU_LE
|
||||||
#define CRC_NUM_TABLES 8
|
#define CRC_NUM_TABLES 8
|
||||||
#else
|
#else
|
||||||
#define CRC_NUM_TABLES 1
|
#define CRC_NUM_TABLES 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||||
|
|
||||||
static CRC_FUNC g_CrcUpdate;
|
static CRC_FUNC g_CrcUpdate;
|
||||||
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
|
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
|
||||||
|
|
||||||
#if CRC_NUM_TABLES == 1
|
#if CRC_NUM_TABLES == 1
|
||||||
|
|
||||||
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||||
|
|
||||||
static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||||
{
|
{
|
||||||
const Byte *p = (const Byte *)data;
|
const Byte *p = (const Byte *)data;
|
||||||
for (; size > 0; size--, p++)
|
for (; size > 0; size--, p++)
|
||||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||||
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
|
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
return g_CrcUpdate(v, data, size, g_CrcTable);
|
return g_CrcUpdate(v, data, size, g_CrcTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
|
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
|
||||||
{
|
{
|
||||||
return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
|
return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MY_FAST_CALL CrcGenerateTable()
|
void MY_FAST_CALL CrcGenerateTable()
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
UInt32 r = i;
|
UInt32 r = i;
|
||||||
unsigned j;
|
unsigned j;
|
||||||
for (j = 0; j < 8; j++)
|
for (j = 0; j < 8; j++)
|
||||||
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
||||||
g_CrcTable[i] = r;
|
g_CrcTable[i] = r;
|
||||||
}
|
}
|
||||||
#if CRC_NUM_TABLES == 1
|
#if CRC_NUM_TABLES == 1
|
||||||
g_CrcUpdate = CrcUpdateT1;
|
g_CrcUpdate = CrcUpdateT1;
|
||||||
#else
|
#else
|
||||||
for (; i < 256 * CRC_NUM_TABLES; i++)
|
for (; i < 256 * CRC_NUM_TABLES; i++)
|
||||||
{
|
{
|
||||||
UInt32 r = g_CrcTable[i - 256];
|
UInt32 r = g_CrcTable[i - 256];
|
||||||
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
|
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
|
||||||
}
|
}
|
||||||
g_CrcUpdate = CrcUpdateT4;
|
g_CrcUpdate = CrcUpdateT4;
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
if (!CPU_Is_InOrder())
|
if (!CPU_Is_InOrder())
|
||||||
g_CrcUpdate = CrcUpdateT8;
|
g_CrcUpdate = CrcUpdateT8;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
/* 7zCrc.h -- CRC32 calculation
|
/* 7zCrc.h -- CRC32 calculation
|
||||||
2009-11-21 : Igor Pavlov : Public domain */
|
2009-11-21 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_CRC_H
|
#ifndef __7Z_CRC_H
|
||||||
#define __7Z_CRC_H
|
#define __7Z_CRC_H
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
EXTERN_C_BEGIN
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
extern UInt32 g_CrcTable[];
|
extern UInt32 g_CrcTable[];
|
||||||
|
|
||||||
/* Call CrcGenerateTable one time before other CRC functions */
|
/* Call CrcGenerateTable one time before other CRC functions */
|
||||||
void MY_FAST_CALL CrcGenerateTable(void);
|
void MY_FAST_CALL CrcGenerateTable(void);
|
||||||
|
|
||||||
#define CRC_INIT_VAL 0xFFFFFFFF
|
#define CRC_INIT_VAL 0xFFFFFFFF
|
||||||
#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL)
|
#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL)
|
||||||
#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
#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 CrcUpdate(UInt32 crc, const void *data, size_t size);
|
||||||
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
|
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,34 +1,34 @@
|
||||||
/* 7zCrcOpt.c -- CRC32 calculation : optimized version
|
/* 7zCrcOpt.c -- CRC32 calculation : optimized version
|
||||||
2009-11-23 : Igor Pavlov : Public domain */
|
2009-11-23 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
|
||||||
#ifdef MY_CPU_LE
|
#ifdef MY_CPU_LE
|
||||||
|
|
||||||
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||||
|
|
||||||
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||||
{
|
{
|
||||||
const Byte *p = (const Byte *)data;
|
const Byte *p = (const Byte *)data;
|
||||||
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
|
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
|
||||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||||
for (; size >= 4; size -= 4, p += 4)
|
for (; size >= 4; size -= 4, p += 4)
|
||||||
{
|
{
|
||||||
v ^= *(const UInt32 *)p;
|
v ^= *(const UInt32 *)p;
|
||||||
v =
|
v =
|
||||||
table[0x300 + (v & 0xFF)] ^
|
table[0x300 + (v & 0xFF)] ^
|
||||||
table[0x200 + ((v >> 8) & 0xFF)] ^
|
table[0x200 + ((v >> 8) & 0xFF)] ^
|
||||||
table[0x100 + ((v >> 16) & 0xFF)] ^
|
table[0x100 + ((v >> 16) & 0xFF)] ^
|
||||||
table[0x000 + ((v >> 24))];
|
table[0x000 + ((v >> 24))];
|
||||||
}
|
}
|
||||||
for (; size > 0; size--, p++)
|
for (; size > 0; size--, p++)
|
||||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||||
{
|
{
|
||||||
return CrcUpdateT4(v, data, size, table);
|
return CrcUpdateT4(v, data, size, table);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,470 +1,470 @@
|
||||||
/* 7zDec.c -- Decoding from 7z folder
|
/* 7zDec.c -- Decoding from 7z folder
|
||||||
2010-11-02 : Igor Pavlov : Public domain */
|
2010-11-02 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* #define _7ZIP_PPMD_SUPPPORT */
|
/* #define _7ZIP_PPMD_SUPPPORT */
|
||||||
|
|
||||||
#include "7z.h"
|
#include "7z.h"
|
||||||
|
|
||||||
#include "Bcj2.h"
|
#include "Bcj2.h"
|
||||||
#include "Bra.h"
|
#include "Bra.h"
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
#include "LzmaDec.h"
|
#include "LzmaDec.h"
|
||||||
#include "Lzma2Dec.h"
|
#include "Lzma2Dec.h"
|
||||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||||
#include "Ppmd7.h"
|
#include "Ppmd7.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define k_Copy 0
|
#define k_Copy 0
|
||||||
#define k_LZMA2 0x21
|
#define k_LZMA2 0x21
|
||||||
#define k_LZMA 0x30101
|
#define k_LZMA 0x30101
|
||||||
#define k_BCJ 0x03030103
|
#define k_BCJ 0x03030103
|
||||||
#define k_PPC 0x03030205
|
#define k_PPC 0x03030205
|
||||||
#define k_ARM 0x03030501
|
#define k_ARM 0x03030501
|
||||||
#define k_ARMT 0x03030701
|
#define k_ARMT 0x03030701
|
||||||
#define k_SPARC 0x03030805
|
#define k_SPARC 0x03030805
|
||||||
#define k_BCJ2 0x0303011B
|
#define k_BCJ2 0x0303011B
|
||||||
|
|
||||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||||
|
|
||||||
#define k_PPMD 0x30401
|
#define k_PPMD 0x30401
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IByteIn p;
|
IByteIn p;
|
||||||
const Byte *cur;
|
const Byte *cur;
|
||||||
const Byte *end;
|
const Byte *end;
|
||||||
const Byte *begin;
|
const Byte *begin;
|
||||||
UInt64 processed;
|
UInt64 processed;
|
||||||
Bool extra;
|
Bool extra;
|
||||||
SRes res;
|
SRes res;
|
||||||
ILookInStream *inStream;
|
ILookInStream *inStream;
|
||||||
} CByteInToLook;
|
} CByteInToLook;
|
||||||
|
|
||||||
static Byte ReadByte(void *pp)
|
static Byte ReadByte(void *pp)
|
||||||
{
|
{
|
||||||
CByteInToLook *p = (CByteInToLook *)pp;
|
CByteInToLook *p = (CByteInToLook *)pp;
|
||||||
if (p->cur != p->end)
|
if (p->cur != p->end)
|
||||||
return *p->cur++;
|
return *p->cur++;
|
||||||
if (p->res == SZ_OK)
|
if (p->res == SZ_OK)
|
||||||
{
|
{
|
||||||
size_t size = p->cur - p->begin;
|
size_t size = p->cur - p->begin;
|
||||||
p->processed += size;
|
p->processed += size;
|
||||||
p->res = p->inStream->Skip(p->inStream, size);
|
p->res = p->inStream->Skip(p->inStream, size);
|
||||||
size = (1 << 25);
|
size = (1 << 25);
|
||||||
p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size);
|
p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size);
|
||||||
p->cur = p->begin;
|
p->cur = p->begin;
|
||||||
p->end = p->begin + size;
|
p->end = p->begin + size;
|
||||||
if (size != 0)
|
if (size != 0)
|
||||||
return *p->cur++;;
|
return *p->cur++;;
|
||||||
}
|
}
|
||||||
p->extra = True;
|
p->extra = True;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||||
{
|
{
|
||||||
CPpmd7 ppmd;
|
CPpmd7 ppmd;
|
||||||
CByteInToLook s;
|
CByteInToLook s;
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
|
|
||||||
s.p.Read = ReadByte;
|
s.p.Read = ReadByte;
|
||||||
s.inStream = inStream;
|
s.inStream = inStream;
|
||||||
s.begin = s.end = s.cur = NULL;
|
s.begin = s.end = s.cur = NULL;
|
||||||
s.extra = False;
|
s.extra = False;
|
||||||
s.res = SZ_OK;
|
s.res = SZ_OK;
|
||||||
s.processed = 0;
|
s.processed = 0;
|
||||||
|
|
||||||
if (coder->Props.size != 5)
|
if (coder->Props.size != 5)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned order = coder->Props.data[0];
|
unsigned order = coder->Props.data[0];
|
||||||
UInt32 memSize = GetUi32(coder->Props.data + 1);
|
UInt32 memSize = GetUi32(coder->Props.data + 1);
|
||||||
if (order < PPMD7_MIN_ORDER ||
|
if (order < PPMD7_MIN_ORDER ||
|
||||||
order > PPMD7_MAX_ORDER ||
|
order > PPMD7_MAX_ORDER ||
|
||||||
memSize < PPMD7_MIN_MEM_SIZE ||
|
memSize < PPMD7_MIN_MEM_SIZE ||
|
||||||
memSize > PPMD7_MAX_MEM_SIZE)
|
memSize > PPMD7_MAX_MEM_SIZE)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
Ppmd7_Construct(&ppmd);
|
Ppmd7_Construct(&ppmd);
|
||||||
if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
|
if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
Ppmd7_Init(&ppmd, order);
|
Ppmd7_Init(&ppmd, order);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CPpmd7z_RangeDec rc;
|
CPpmd7z_RangeDec rc;
|
||||||
Ppmd7z_RangeDec_CreateVTable(&rc);
|
Ppmd7z_RangeDec_CreateVTable(&rc);
|
||||||
rc.Stream = &s.p;
|
rc.Stream = &s.p;
|
||||||
if (!Ppmd7z_RangeDec_Init(&rc))
|
if (!Ppmd7z_RangeDec_Init(&rc))
|
||||||
res = SZ_ERROR_DATA;
|
res = SZ_ERROR_DATA;
|
||||||
else if (s.extra)
|
else if (s.extra)
|
||||||
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
|
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SizeT i;
|
SizeT i;
|
||||||
for (i = 0; i < outSize; i++)
|
for (i = 0; i < outSize; i++)
|
||||||
{
|
{
|
||||||
int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);
|
int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);
|
||||||
if (s.extra || sym < 0)
|
if (s.extra || sym < 0)
|
||||||
break;
|
break;
|
||||||
outBuffer[i] = (Byte)sym;
|
outBuffer[i] = (Byte)sym;
|
||||||
}
|
}
|
||||||
if (i != outSize)
|
if (i != outSize)
|
||||||
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
|
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
|
||||||
else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))
|
else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))
|
||||||
res = SZ_ERROR_DATA;
|
res = SZ_ERROR_DATA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ppmd7_Free(&ppmd, allocMain);
|
Ppmd7_Free(&ppmd, allocMain);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||||
{
|
{
|
||||||
CLzmaDec state;
|
CLzmaDec state;
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
|
|
||||||
LzmaDec_Construct(&state);
|
LzmaDec_Construct(&state);
|
||||||
RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
|
RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
|
||||||
state.dic = outBuffer;
|
state.dic = outBuffer;
|
||||||
state.dicBufSize = outSize;
|
state.dicBufSize = outSize;
|
||||||
LzmaDec_Init(&state);
|
LzmaDec_Init(&state);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Byte *inBuf = NULL;
|
Byte *inBuf = NULL;
|
||||||
size_t lookahead = (1 << 18);
|
size_t lookahead = (1 << 18);
|
||||||
if (lookahead > inSize)
|
if (lookahead > inSize)
|
||||||
lookahead = (size_t)inSize;
|
lookahead = (size_t)inSize;
|
||||||
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
{
|
{
|
||||||
SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
|
SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
|
||||||
ELzmaStatus status;
|
ELzmaStatus status;
|
||||||
res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
|
res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
|
||||||
lookahead -= inProcessed;
|
lookahead -= inProcessed;
|
||||||
inSize -= inProcessed;
|
inSize -= inProcessed;
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
|
if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
|
||||||
{
|
{
|
||||||
if (state.dicBufSize != outSize || lookahead != 0 ||
|
if (state.dicBufSize != outSize || lookahead != 0 ||
|
||||||
(status != LZMA_STATUS_FINISHED_WITH_MARK &&
|
(status != LZMA_STATUS_FINISHED_WITH_MARK &&
|
||||||
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
|
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
|
||||||
res = SZ_ERROR_DATA;
|
res = SZ_ERROR_DATA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
res = inStream->Skip((void *)inStream, inProcessed);
|
res = inStream->Skip((void *)inStream, inProcessed);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LzmaDec_FreeProbs(&state, allocMain);
|
LzmaDec_FreeProbs(&state, allocMain);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||||
{
|
{
|
||||||
CLzma2Dec state;
|
CLzma2Dec state;
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
|
|
||||||
Lzma2Dec_Construct(&state);
|
Lzma2Dec_Construct(&state);
|
||||||
if (coder->Props.size != 1)
|
if (coder->Props.size != 1)
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain));
|
RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain));
|
||||||
state.decoder.dic = outBuffer;
|
state.decoder.dic = outBuffer;
|
||||||
state.decoder.dicBufSize = outSize;
|
state.decoder.dicBufSize = outSize;
|
||||||
Lzma2Dec_Init(&state);
|
Lzma2Dec_Init(&state);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Byte *inBuf = NULL;
|
Byte *inBuf = NULL;
|
||||||
size_t lookahead = (1 << 18);
|
size_t lookahead = (1 << 18);
|
||||||
if (lookahead > inSize)
|
if (lookahead > inSize)
|
||||||
lookahead = (size_t)inSize;
|
lookahead = (size_t)inSize;
|
||||||
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
{
|
{
|
||||||
SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
|
SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
|
||||||
ELzmaStatus status;
|
ELzmaStatus status;
|
||||||
res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
|
res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
|
||||||
lookahead -= inProcessed;
|
lookahead -= inProcessed;
|
||||||
inSize -= inProcessed;
|
inSize -= inProcessed;
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))
|
if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))
|
||||||
{
|
{
|
||||||
if (state.decoder.dicBufSize != outSize || lookahead != 0 ||
|
if (state.decoder.dicBufSize != outSize || lookahead != 0 ||
|
||||||
(status != LZMA_STATUS_FINISHED_WITH_MARK))
|
(status != LZMA_STATUS_FINISHED_WITH_MARK))
|
||||||
res = SZ_ERROR_DATA;
|
res = SZ_ERROR_DATA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
res = inStream->Skip((void *)inStream, inProcessed);
|
res = inStream->Skip((void *)inStream, inProcessed);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Lzma2Dec_FreeProbs(&state, allocMain);
|
Lzma2Dec_FreeProbs(&state, allocMain);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
|
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
|
||||||
{
|
{
|
||||||
while (inSize > 0)
|
while (inSize > 0)
|
||||||
{
|
{
|
||||||
void *inBuf;
|
void *inBuf;
|
||||||
size_t curSize = (1 << 18);
|
size_t curSize = (1 << 18);
|
||||||
if (curSize > inSize)
|
if (curSize > inSize)
|
||||||
curSize = (size_t)inSize;
|
curSize = (size_t)inSize;
|
||||||
RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize));
|
RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize));
|
||||||
if (curSize == 0)
|
if (curSize == 0)
|
||||||
return SZ_ERROR_INPUT_EOF;
|
return SZ_ERROR_INPUT_EOF;
|
||||||
memcpy(outBuffer, inBuf, curSize);
|
memcpy(outBuffer, inBuf, curSize);
|
||||||
outBuffer += curSize;
|
outBuffer += curSize;
|
||||||
inSize -= curSize;
|
inSize -= curSize;
|
||||||
RINOK(inStream->Skip((void *)inStream, curSize));
|
RINOK(inStream->Skip((void *)inStream, curSize));
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool IS_MAIN_METHOD(UInt32 m)
|
static Bool IS_MAIN_METHOD(UInt32 m)
|
||||||
{
|
{
|
||||||
switch(m)
|
switch(m)
|
||||||
{
|
{
|
||||||
case k_Copy:
|
case k_Copy:
|
||||||
case k_LZMA:
|
case k_LZMA:
|
||||||
case k_LZMA2:
|
case k_LZMA2:
|
||||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||||
case k_PPMD:
|
case k_PPMD:
|
||||||
#endif
|
#endif
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
|
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
c->NumInStreams == 1 &&
|
c->NumInStreams == 1 &&
|
||||||
c->NumOutStreams == 1 &&
|
c->NumOutStreams == 1 &&
|
||||||
c->MethodID <= (UInt32)0xFFFFFFFF &&
|
c->MethodID <= (UInt32)0xFFFFFFFF &&
|
||||||
IS_MAIN_METHOD((UInt32)c->MethodID);
|
IS_MAIN_METHOD((UInt32)c->MethodID);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
|
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
|
||||||
|
|
||||||
static SRes CheckSupportedFolder(const CSzFolder *f)
|
static SRes CheckSupportedFolder(const CSzFolder *f)
|
||||||
{
|
{
|
||||||
if (f->NumCoders < 1 || f->NumCoders > 4)
|
if (f->NumCoders < 1 || f->NumCoders > 4)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
if (!IS_SUPPORTED_CODER(&f->Coders[0]))
|
if (!IS_SUPPORTED_CODER(&f->Coders[0]))
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
if (f->NumCoders == 1)
|
if (f->NumCoders == 1)
|
||||||
{
|
{
|
||||||
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
|
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
if (f->NumCoders == 2)
|
if (f->NumCoders == 2)
|
||||||
{
|
{
|
||||||
CSzCoderInfo *c = &f->Coders[1];
|
CSzCoderInfo *c = &f->Coders[1];
|
||||||
if (c->MethodID > (UInt32)0xFFFFFFFF ||
|
if (c->MethodID > (UInt32)0xFFFFFFFF ||
|
||||||
c->NumInStreams != 1 ||
|
c->NumInStreams != 1 ||
|
||||||
c->NumOutStreams != 1 ||
|
c->NumOutStreams != 1 ||
|
||||||
f->NumPackStreams != 1 ||
|
f->NumPackStreams != 1 ||
|
||||||
f->PackStreams[0] != 0 ||
|
f->PackStreams[0] != 0 ||
|
||||||
f->NumBindPairs != 1 ||
|
f->NumBindPairs != 1 ||
|
||||||
f->BindPairs[0].InIndex != 1 ||
|
f->BindPairs[0].InIndex != 1 ||
|
||||||
f->BindPairs[0].OutIndex != 0)
|
f->BindPairs[0].OutIndex != 0)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
switch ((UInt32)c->MethodID)
|
switch ((UInt32)c->MethodID)
|
||||||
{
|
{
|
||||||
case k_BCJ:
|
case k_BCJ:
|
||||||
case k_ARM:
|
case k_ARM:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
if (f->NumCoders == 4)
|
if (f->NumCoders == 4)
|
||||||
{
|
{
|
||||||
if (!IS_SUPPORTED_CODER(&f->Coders[1]) ||
|
if (!IS_SUPPORTED_CODER(&f->Coders[1]) ||
|
||||||
!IS_SUPPORTED_CODER(&f->Coders[2]) ||
|
!IS_SUPPORTED_CODER(&f->Coders[2]) ||
|
||||||
!IS_BCJ2(&f->Coders[3]))
|
!IS_BCJ2(&f->Coders[3]))
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
if (f->NumPackStreams != 4 ||
|
if (f->NumPackStreams != 4 ||
|
||||||
f->PackStreams[0] != 2 ||
|
f->PackStreams[0] != 2 ||
|
||||||
f->PackStreams[1] != 6 ||
|
f->PackStreams[1] != 6 ||
|
||||||
f->PackStreams[2] != 1 ||
|
f->PackStreams[2] != 1 ||
|
||||||
f->PackStreams[3] != 0 ||
|
f->PackStreams[3] != 0 ||
|
||||||
f->NumBindPairs != 3 ||
|
f->NumBindPairs != 3 ||
|
||||||
f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
|
f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
|
||||||
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
|
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
|
||||||
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
|
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UInt64 GetSum(const UInt64 *values, UInt32 index)
|
static UInt64 GetSum(const UInt64 *values, UInt32 index)
|
||||||
{
|
{
|
||||||
UInt64 sum = 0;
|
UInt64 sum = 0;
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
for (i = 0; i < index; i++)
|
for (i = 0; i < index; i++)
|
||||||
sum += values[i];
|
sum += values[i];
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
|
#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
|
||||||
|
|
||||||
static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
|
static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
|
||||||
ILookInStream *inStream, UInt64 startPos,
|
ILookInStream *inStream, UInt64 startPos,
|
||||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
|
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
|
||||||
Byte *tempBuf[])
|
Byte *tempBuf[])
|
||||||
{
|
{
|
||||||
UInt32 ci;
|
UInt32 ci;
|
||||||
SizeT tempSizes[3] = { 0, 0, 0};
|
SizeT tempSizes[3] = { 0, 0, 0};
|
||||||
SizeT tempSize3 = 0;
|
SizeT tempSize3 = 0;
|
||||||
Byte *tempBuf3 = 0;
|
Byte *tempBuf3 = 0;
|
||||||
|
|
||||||
RINOK(CheckSupportedFolder(folder));
|
RINOK(CheckSupportedFolder(folder));
|
||||||
|
|
||||||
for (ci = 0; ci < folder->NumCoders; ci++)
|
for (ci = 0; ci < folder->NumCoders; ci++)
|
||||||
{
|
{
|
||||||
CSzCoderInfo *coder = &folder->Coders[ci];
|
CSzCoderInfo *coder = &folder->Coders[ci];
|
||||||
|
|
||||||
if (IS_MAIN_METHOD((UInt32)coder->MethodID))
|
if (IS_MAIN_METHOD((UInt32)coder->MethodID))
|
||||||
{
|
{
|
||||||
UInt32 si = 0;
|
UInt32 si = 0;
|
||||||
UInt64 offset;
|
UInt64 offset;
|
||||||
UInt64 inSize;
|
UInt64 inSize;
|
||||||
Byte *outBufCur = outBuffer;
|
Byte *outBufCur = outBuffer;
|
||||||
SizeT outSizeCur = outSize;
|
SizeT outSizeCur = outSize;
|
||||||
if (folder->NumCoders == 4)
|
if (folder->NumCoders == 4)
|
||||||
{
|
{
|
||||||
UInt32 indices[] = { 3, 2, 0 };
|
UInt32 indices[] = { 3, 2, 0 };
|
||||||
UInt64 unpackSize = folder->UnpackSizes[ci];
|
UInt64 unpackSize = folder->UnpackSizes[ci];
|
||||||
si = indices[ci];
|
si = indices[ci];
|
||||||
if (ci < 2)
|
if (ci < 2)
|
||||||
{
|
{
|
||||||
Byte *temp;
|
Byte *temp;
|
||||||
outSizeCur = (SizeT)unpackSize;
|
outSizeCur = (SizeT)unpackSize;
|
||||||
if (outSizeCur != unpackSize)
|
if (outSizeCur != unpackSize)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
|
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
|
||||||
if (temp == 0 && outSizeCur != 0)
|
if (temp == 0 && outSizeCur != 0)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
outBufCur = tempBuf[1 - ci] = temp;
|
outBufCur = tempBuf[1 - ci] = temp;
|
||||||
tempSizes[1 - ci] = outSizeCur;
|
tempSizes[1 - ci] = outSizeCur;
|
||||||
}
|
}
|
||||||
else if (ci == 2)
|
else if (ci == 2)
|
||||||
{
|
{
|
||||||
if (unpackSize > outSize) /* check it */
|
if (unpackSize > outSize) /* check it */
|
||||||
return SZ_ERROR_PARAM;
|
return SZ_ERROR_PARAM;
|
||||||
tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
|
tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
|
||||||
tempSize3 = outSizeCur = (SizeT)unpackSize;
|
tempSize3 = outSizeCur = (SizeT)unpackSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
offset = GetSum(packSizes, si);
|
offset = GetSum(packSizes, si);
|
||||||
inSize = packSizes[si];
|
inSize = packSizes[si];
|
||||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||||
|
|
||||||
if (coder->MethodID == k_Copy)
|
if (coder->MethodID == k_Copy)
|
||||||
{
|
{
|
||||||
if (inSize != outSizeCur) /* check it */
|
if (inSize != outSizeCur) /* check it */
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
|
RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
|
||||||
}
|
}
|
||||||
else if (coder->MethodID == k_LZMA)
|
else if (coder->MethodID == k_LZMA)
|
||||||
{
|
{
|
||||||
RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||||
}
|
}
|
||||||
else if (coder->MethodID == k_LZMA2)
|
else if (coder->MethodID == k_LZMA2)
|
||||||
{
|
{
|
||||||
RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||||
RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||||
#else
|
#else
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (coder->MethodID == k_BCJ2)
|
else if (coder->MethodID == k_BCJ2)
|
||||||
{
|
{
|
||||||
UInt64 offset = GetSum(packSizes, 1);
|
UInt64 offset = GetSum(packSizes, 1);
|
||||||
UInt64 s3Size = packSizes[1];
|
UInt64 s3Size = packSizes[1];
|
||||||
SRes res;
|
SRes res;
|
||||||
if (ci != 3)
|
if (ci != 3)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||||
tempSizes[2] = (SizeT)s3Size;
|
tempSizes[2] = (SizeT)s3Size;
|
||||||
if (tempSizes[2] != s3Size)
|
if (tempSizes[2] != s3Size)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
|
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
|
||||||
if (tempBuf[2] == 0 && tempSizes[2] != 0)
|
if (tempBuf[2] == 0 && tempSizes[2] != 0)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
|
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
|
||||||
RINOK(res)
|
RINOK(res)
|
||||||
|
|
||||||
res = Bcj2_Decode(
|
res = Bcj2_Decode(
|
||||||
tempBuf3, tempSize3,
|
tempBuf3, tempSize3,
|
||||||
tempBuf[0], tempSizes[0],
|
tempBuf[0], tempSizes[0],
|
||||||
tempBuf[1], tempSizes[1],
|
tempBuf[1], tempSizes[1],
|
||||||
tempBuf[2], tempSizes[2],
|
tempBuf[2], tempSizes[2],
|
||||||
outBuffer, outSize);
|
outBuffer, outSize);
|
||||||
RINOK(res)
|
RINOK(res)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ci != 1)
|
if (ci != 1)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
switch(coder->MethodID)
|
switch(coder->MethodID)
|
||||||
{
|
{
|
||||||
case k_BCJ:
|
case k_BCJ:
|
||||||
{
|
{
|
||||||
UInt32 state;
|
UInt32 state;
|
||||||
x86_Convert_Init(state);
|
x86_Convert_Init(state);
|
||||||
x86_Convert(outBuffer, outSize, 0, &state, 0);
|
x86_Convert(outBuffer, outSize, 0, &state, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CASE_BRA_CONV(ARM)
|
CASE_BRA_CONV(ARM)
|
||||||
default:
|
default:
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
|
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
|
||||||
ILookInStream *inStream, UInt64 startPos,
|
ILookInStream *inStream, UInt64 startPos,
|
||||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
|
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
|
||||||
{
|
{
|
||||||
Byte *tempBuf[3] = { 0, 0, 0};
|
Byte *tempBuf[3] = { 0, 0, 0};
|
||||||
int i;
|
int i;
|
||||||
SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos,
|
SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos,
|
||||||
outBuffer, (SizeT)outSize, allocMain, tempBuf);
|
outBuffer, (SizeT)outSize, allocMain, tempBuf);
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
IAlloc_Free(allocMain, tempBuf[i]);
|
IAlloc_Free(allocMain, tempBuf[i]);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
/* 7zDecode.h -- Decoding from 7z folder
|
/* 7zDecode.h -- Decoding from 7z folder
|
||||||
2008-11-23 : Igor Pavlov : Public domain */
|
2008-11-23 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_DECODE_H
|
#ifndef __7Z_DECODE_H
|
||||||
#define __7Z_DECODE_H
|
#define __7Z_DECODE_H
|
||||||
|
|
||||||
#include "7zItem.h"
|
#include "7zItem.h"
|
||||||
|
|
||||||
SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
|
SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
|
||||||
ILookInStream *stream, UInt64 startPos,
|
ILookInStream *stream, UInt64 startPos,
|
||||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
|
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,93 +1,93 @@
|
||||||
/* 7zExtract.c -- Extracting from 7z archive
|
/* 7zExtract.c -- Extracting from 7z archive
|
||||||
2008-11-23 : Igor Pavlov : Public domain */
|
2008-11-23 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "7zCrc.h"
|
#include "7zCrc.h"
|
||||||
#include "7zDecode.h"
|
#include "7zDecode.h"
|
||||||
#include "7zExtract.h"
|
#include "7zExtract.h"
|
||||||
|
|
||||||
SRes SzAr_Extract(
|
SRes SzAr_Extract(
|
||||||
const CSzArEx *p,
|
const CSzArEx *p,
|
||||||
ILookInStream *inStream,
|
ILookInStream *inStream,
|
||||||
UInt32 fileIndex,
|
UInt32 fileIndex,
|
||||||
UInt32 *blockIndex,
|
UInt32 *blockIndex,
|
||||||
Byte **outBuffer,
|
Byte **outBuffer,
|
||||||
size_t *outBufferSize,
|
size_t *outBufferSize,
|
||||||
size_t *offset,
|
size_t *offset,
|
||||||
size_t *outSizeProcessed,
|
size_t *outSizeProcessed,
|
||||||
ISzAlloc *allocMain,
|
ISzAlloc *allocMain,
|
||||||
ISzAlloc *allocTemp)
|
ISzAlloc *allocTemp)
|
||||||
{
|
{
|
||||||
UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
|
UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
*offset = 0;
|
*offset = 0;
|
||||||
*outSizeProcessed = 0;
|
*outSizeProcessed = 0;
|
||||||
if (folderIndex == (UInt32)-1)
|
if (folderIndex == (UInt32)-1)
|
||||||
{
|
{
|
||||||
IAlloc_Free(allocMain, *outBuffer);
|
IAlloc_Free(allocMain, *outBuffer);
|
||||||
*blockIndex = folderIndex;
|
*blockIndex = folderIndex;
|
||||||
*outBuffer = 0;
|
*outBuffer = 0;
|
||||||
*outBufferSize = 0;
|
*outBufferSize = 0;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*outBuffer == 0 || *blockIndex != folderIndex)
|
if (*outBuffer == 0 || *blockIndex != folderIndex)
|
||||||
{
|
{
|
||||||
CSzFolder *folder = p->db.Folders + folderIndex;
|
CSzFolder *folder = p->db.Folders + folderIndex;
|
||||||
UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder);
|
UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder);
|
||||||
size_t unpackSize = (size_t)unpackSizeSpec;
|
size_t unpackSize = (size_t)unpackSizeSpec;
|
||||||
UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);
|
UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);
|
||||||
|
|
||||||
if (unpackSize != unpackSizeSpec)
|
if (unpackSize != unpackSizeSpec)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
*blockIndex = folderIndex;
|
*blockIndex = folderIndex;
|
||||||
IAlloc_Free(allocMain, *outBuffer);
|
IAlloc_Free(allocMain, *outBuffer);
|
||||||
*outBuffer = 0;
|
*outBuffer = 0;
|
||||||
|
|
||||||
RINOK(LookInStream_SeekTo(inStream, startOffset));
|
RINOK(LookInStream_SeekTo(inStream, startOffset));
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
*outBufferSize = unpackSize;
|
*outBufferSize = unpackSize;
|
||||||
if (unpackSize != 0)
|
if (unpackSize != 0)
|
||||||
{
|
{
|
||||||
*outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
|
*outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
|
||||||
if (*outBuffer == 0)
|
if (*outBuffer == 0)
|
||||||
res = SZ_ERROR_MEM;
|
res = SZ_ERROR_MEM;
|
||||||
}
|
}
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
res = SzDecode(p->db.PackSizes +
|
res = SzDecode(p->db.PackSizes +
|
||||||
p->FolderStartPackStreamIndex[folderIndex], folder,
|
p->FolderStartPackStreamIndex[folderIndex], folder,
|
||||||
inStream, startOffset,
|
inStream, startOffset,
|
||||||
*outBuffer, unpackSize, allocTemp);
|
*outBuffer, unpackSize, allocTemp);
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
if (folder->UnpackCRCDefined)
|
if (folder->UnpackCRCDefined)
|
||||||
{
|
{
|
||||||
if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)
|
if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)
|
||||||
res = SZ_ERROR_CRC;
|
res = SZ_ERROR_CRC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
CSzFileItem *fileItem = p->db.Files + fileIndex;
|
CSzFileItem *fileItem = p->db.Files + fileIndex;
|
||||||
*offset = 0;
|
*offset = 0;
|
||||||
for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
||||||
*offset += (UInt32)p->db.Files[i].Size;
|
*offset += (UInt32)p->db.Files[i].Size;
|
||||||
*outSizeProcessed = (size_t)fileItem->Size;
|
*outSizeProcessed = (size_t)fileItem->Size;
|
||||||
if (*offset + *outSizeProcessed > *outBufferSize)
|
if (*offset + *outSizeProcessed > *outBufferSize)
|
||||||
return SZ_ERROR_FAIL;
|
return SZ_ERROR_FAIL;
|
||||||
{
|
{
|
||||||
if (fileItem->FileCRCDefined)
|
if (fileItem->FileCRCDefined)
|
||||||
{
|
{
|
||||||
if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)
|
if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)
|
||||||
res = SZ_ERROR_CRC;
|
res = SZ_ERROR_CRC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,49 +1,49 @@
|
||||||
/* 7zExtract.h -- Extracting from 7z archive
|
/* 7zExtract.h -- Extracting from 7z archive
|
||||||
2008-11-23 : Igor Pavlov : Public domain */
|
2008-11-23 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_EXTRACT_H
|
#ifndef __7Z_EXTRACT_H
|
||||||
#define __7Z_EXTRACT_H
|
#define __7Z_EXTRACT_H
|
||||||
|
|
||||||
#include "7zIn.h"
|
#include "7zIn.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SzExtract extracts file from archive
|
SzExtract extracts file from archive
|
||||||
|
|
||||||
*outBuffer must be 0 before first call for each new archive.
|
*outBuffer must be 0 before first call for each new archive.
|
||||||
|
|
||||||
Extracting cache:
|
Extracting cache:
|
||||||
If you need to decompress more than one file, you can send
|
If you need to decompress more than one file, you can send
|
||||||
these values from previous call:
|
these values from previous call:
|
||||||
*blockIndex,
|
*blockIndex,
|
||||||
*outBuffer,
|
*outBuffer,
|
||||||
*outBufferSize
|
*outBufferSize
|
||||||
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
||||||
it will increase decompression speed.
|
it will increase decompression speed.
|
||||||
|
|
||||||
If you use external function, you can declare these 3 cache variables
|
If you use external function, you can declare these 3 cache variables
|
||||||
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
||||||
|
|
||||||
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SRes SzAr_Extract(
|
SRes SzAr_Extract(
|
||||||
const CSzArEx *db,
|
const CSzArEx *db,
|
||||||
ILookInStream *inStream,
|
ILookInStream *inStream,
|
||||||
UInt32 fileIndex, /* index of file */
|
UInt32 fileIndex, /* index of file */
|
||||||
UInt32 *blockIndex, /* index of solid block */
|
UInt32 *blockIndex, /* index of solid block */
|
||||||
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
||||||
size_t *outBufferSize, /* buffer size for output buffer */
|
size_t *outBufferSize, /* buffer size for output buffer */
|
||||||
size_t *offset, /* offset of stream for required file in *outBuffer */
|
size_t *offset, /* offset of stream for required file in *outBuffer */
|
||||||
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
||||||
ISzAlloc *allocMain,
|
ISzAlloc *allocMain,
|
||||||
ISzAlloc *allocTemp);
|
ISzAlloc *allocTemp);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* 7zHeader.c -- 7z Headers
|
/* 7zHeader.c -- 7z Headers
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
2008-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "7zHeader.h"
|
#include "7zHeader.h"
|
||||||
|
|
||||||
Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
||||||
|
|
|
@ -1,57 +1,57 @@
|
||||||
/* 7zHeader.h -- 7z Headers
|
/* 7zHeader.h -- 7z Headers
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
2008-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_HEADER_H
|
#ifndef __7Z_HEADER_H
|
||||||
#define __7Z_HEADER_H
|
#define __7Z_HEADER_H
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
#define k7zSignatureSize 6
|
#define k7zSignatureSize 6
|
||||||
extern Byte k7zSignature[k7zSignatureSize];
|
extern Byte k7zSignature[k7zSignatureSize];
|
||||||
|
|
||||||
#define k7zMajorVersion 0
|
#define k7zMajorVersion 0
|
||||||
|
|
||||||
#define k7zStartHeaderSize 0x20
|
#define k7zStartHeaderSize 0x20
|
||||||
|
|
||||||
enum EIdEnum
|
enum EIdEnum
|
||||||
{
|
{
|
||||||
k7zIdEnd,
|
k7zIdEnd,
|
||||||
|
|
||||||
k7zIdHeader,
|
k7zIdHeader,
|
||||||
|
|
||||||
k7zIdArchiveProperties,
|
k7zIdArchiveProperties,
|
||||||
|
|
||||||
k7zIdAdditionalStreamsInfo,
|
k7zIdAdditionalStreamsInfo,
|
||||||
k7zIdMainStreamsInfo,
|
k7zIdMainStreamsInfo,
|
||||||
k7zIdFilesInfo,
|
k7zIdFilesInfo,
|
||||||
|
|
||||||
k7zIdPackInfo,
|
k7zIdPackInfo,
|
||||||
k7zIdUnpackInfo,
|
k7zIdUnpackInfo,
|
||||||
k7zIdSubStreamsInfo,
|
k7zIdSubStreamsInfo,
|
||||||
|
|
||||||
k7zIdSize,
|
k7zIdSize,
|
||||||
k7zIdCRC,
|
k7zIdCRC,
|
||||||
|
|
||||||
k7zIdFolder,
|
k7zIdFolder,
|
||||||
|
|
||||||
k7zIdCodersUnpackSize,
|
k7zIdCodersUnpackSize,
|
||||||
k7zIdNumUnpackStream,
|
k7zIdNumUnpackStream,
|
||||||
|
|
||||||
k7zIdEmptyStream,
|
k7zIdEmptyStream,
|
||||||
k7zIdEmptyFile,
|
k7zIdEmptyFile,
|
||||||
k7zIdAnti,
|
k7zIdAnti,
|
||||||
|
|
||||||
k7zIdName,
|
k7zIdName,
|
||||||
k7zIdCTime,
|
k7zIdCTime,
|
||||||
k7zIdATime,
|
k7zIdATime,
|
||||||
k7zIdMTime,
|
k7zIdMTime,
|
||||||
k7zIdWinAttributes,
|
k7zIdWinAttributes,
|
||||||
k7zIdComment,
|
k7zIdComment,
|
||||||
|
|
||||||
k7zIdEncodedHeader,
|
k7zIdEncodedHeader,
|
||||||
|
|
||||||
k7zIdStartPos,
|
k7zIdStartPos,
|
||||||
k7zIdDummy
|
k7zIdDummy
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
2804
fex/7z_C/7zIn.c
2804
fex/7z_C/7zIn.c
File diff suppressed because it is too large
Load Diff
|
@ -1,49 +1,49 @@
|
||||||
/* 7zIn.h -- 7z Input functions
|
/* 7zIn.h -- 7z Input functions
|
||||||
2008-11-23 : Igor Pavlov : Public domain */
|
2008-11-23 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_IN_H
|
#ifndef __7Z_IN_H
|
||||||
#define __7Z_IN_H
|
#define __7Z_IN_H
|
||||||
|
|
||||||
#include "7zHeader.h"
|
#include "7zHeader.h"
|
||||||
#include "7zItem.h"
|
#include "7zItem.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CSzAr db;
|
CSzAr db;
|
||||||
|
|
||||||
UInt64 startPosAfterHeader;
|
UInt64 startPosAfterHeader;
|
||||||
UInt64 dataPos;
|
UInt64 dataPos;
|
||||||
|
|
||||||
UInt32 *FolderStartPackStreamIndex;
|
UInt32 *FolderStartPackStreamIndex;
|
||||||
UInt64 *PackStreamStartPositions;
|
UInt64 *PackStreamStartPositions;
|
||||||
UInt32 *FolderStartFileIndex;
|
UInt32 *FolderStartFileIndex;
|
||||||
UInt32 *FileIndexToFolderIndexMap;
|
UInt32 *FileIndexToFolderIndexMap;
|
||||||
} CSzArEx;
|
} CSzArEx;
|
||||||
|
|
||||||
void SzArEx_Init(CSzArEx *p);
|
void SzArEx_Init(CSzArEx *p);
|
||||||
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
|
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
|
||||||
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
|
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
|
||||||
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
|
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Errors:
|
Errors:
|
||||||
SZ_ERROR_NO_ARCHIVE
|
SZ_ERROR_NO_ARCHIVE
|
||||||
SZ_ERROR_ARCHIVE
|
SZ_ERROR_ARCHIVE
|
||||||
SZ_ERROR_UNSUPPORTED
|
SZ_ERROR_UNSUPPORTED
|
||||||
SZ_ERROR_MEM
|
SZ_ERROR_MEM
|
||||||
SZ_ERROR_CRC
|
SZ_ERROR_CRC
|
||||||
SZ_ERROR_INPUT_EOF
|
SZ_ERROR_INPUT_EOF
|
||||||
SZ_ERROR_FAIL
|
SZ_ERROR_FAIL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
|
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,129 +1,129 @@
|
||||||
/* 7zItem.c -- 7z Items
|
/* 7zItem.c -- 7z Items
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
2008-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "7zItem.h"
|
#include "7zItem.h"
|
||||||
|
|
||||||
void SzCoderInfo_Init(CSzCoderInfo *p)
|
void SzCoderInfo_Init(CSzCoderInfo *p)
|
||||||
{
|
{
|
||||||
Buf_Init(&p->Props);
|
Buf_Init(&p->Props);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc)
|
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
Buf_Free(&p->Props, alloc);
|
Buf_Free(&p->Props, alloc);
|
||||||
SzCoderInfo_Init(p);
|
SzCoderInfo_Init(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SzFolder_Init(CSzFolder *p)
|
void SzFolder_Init(CSzFolder *p)
|
||||||
{
|
{
|
||||||
p->Coders = 0;
|
p->Coders = 0;
|
||||||
p->BindPairs = 0;
|
p->BindPairs = 0;
|
||||||
p->PackStreams = 0;
|
p->PackStreams = 0;
|
||||||
p->UnpackSizes = 0;
|
p->UnpackSizes = 0;
|
||||||
p->NumCoders = 0;
|
p->NumCoders = 0;
|
||||||
p->NumBindPairs = 0;
|
p->NumBindPairs = 0;
|
||||||
p->NumPackStreams = 0;
|
p->NumPackStreams = 0;
|
||||||
p->UnpackCRCDefined = 0;
|
p->UnpackCRCDefined = 0;
|
||||||
p->UnpackCRC = 0;
|
p->UnpackCRC = 0;
|
||||||
p->NumUnpackStreams = 0;
|
p->NumUnpackStreams = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
|
void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
if (p->Coders)
|
if (p->Coders)
|
||||||
for (i = 0; i < p->NumCoders; i++)
|
for (i = 0; i < p->NumCoders; i++)
|
||||||
SzCoderInfo_Free(&p->Coders[i], alloc);
|
SzCoderInfo_Free(&p->Coders[i], alloc);
|
||||||
IAlloc_Free(alloc, p->Coders);
|
IAlloc_Free(alloc, p->Coders);
|
||||||
IAlloc_Free(alloc, p->BindPairs);
|
IAlloc_Free(alloc, p->BindPairs);
|
||||||
IAlloc_Free(alloc, p->PackStreams);
|
IAlloc_Free(alloc, p->PackStreams);
|
||||||
IAlloc_Free(alloc, p->UnpackSizes);
|
IAlloc_Free(alloc, p->UnpackSizes);
|
||||||
SzFolder_Init(p);
|
SzFolder_Init(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p)
|
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p)
|
||||||
{
|
{
|
||||||
UInt32 result = 0;
|
UInt32 result = 0;
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
for (i = 0; i < p->NumCoders; i++)
|
for (i = 0; i < p->NumCoders; i++)
|
||||||
result += p->Coders[i].NumOutStreams;
|
result += p->Coders[i].NumOutStreams;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex)
|
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
for (i = 0; i < p->NumBindPairs; i++)
|
for (i = 0; i < p->NumBindPairs; i++)
|
||||||
if (p->BindPairs[i].InIndex == inStreamIndex)
|
if (p->BindPairs[i].InIndex == inStreamIndex)
|
||||||
return i;
|
return i;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex)
|
int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
for (i = 0; i < p->NumBindPairs; i++)
|
for (i = 0; i < p->NumBindPairs; i++)
|
||||||
if (p->BindPairs[i].OutIndex == outStreamIndex)
|
if (p->BindPairs[i].OutIndex == outStreamIndex)
|
||||||
return i;
|
return i;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt64 SzFolder_GetUnpackSize(CSzFolder *p)
|
UInt64 SzFolder_GetUnpackSize(CSzFolder *p)
|
||||||
{
|
{
|
||||||
int i = (int)SzFolder_GetNumOutStreams(p);
|
int i = (int)SzFolder_GetNumOutStreams(p);
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
return 0;
|
return 0;
|
||||||
for (i--; i >= 0; i--)
|
for (i--; i >= 0; i--)
|
||||||
if (SzFolder_FindBindPairForOutStream(p, i) < 0)
|
if (SzFolder_FindBindPairForOutStream(p, i) < 0)
|
||||||
return p->UnpackSizes[i];
|
return p->UnpackSizes[i];
|
||||||
/* throw 1; */
|
/* throw 1; */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SzFile_Init(CSzFileItem *p)
|
void SzFile_Init(CSzFileItem *p)
|
||||||
{
|
{
|
||||||
p->HasStream = 1;
|
p->HasStream = 1;
|
||||||
p->IsDir = 0;
|
p->IsDir = 0;
|
||||||
p->IsAnti = 0;
|
p->IsAnti = 0;
|
||||||
p->FileCRCDefined = 0;
|
p->FileCRCDefined = 0;
|
||||||
p->MTimeDefined = 0;
|
p->MTimeDefined = 0;
|
||||||
p->Name = 0;
|
p->Name = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SzFile_Free(CSzFileItem *p, ISzAlloc *alloc)
|
static void SzFile_Free(CSzFileItem *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
IAlloc_Free(alloc, p->Name);
|
IAlloc_Free(alloc, p->Name);
|
||||||
SzFile_Init(p);
|
SzFile_Init(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SzAr_Init(CSzAr *p)
|
void SzAr_Init(CSzAr *p)
|
||||||
{
|
{
|
||||||
p->PackSizes = 0;
|
p->PackSizes = 0;
|
||||||
p->PackCRCsDefined = 0;
|
p->PackCRCsDefined = 0;
|
||||||
p->PackCRCs = 0;
|
p->PackCRCs = 0;
|
||||||
p->Folders = 0;
|
p->Folders = 0;
|
||||||
p->Files = 0;
|
p->Files = 0;
|
||||||
p->NumPackStreams = 0;
|
p->NumPackStreams = 0;
|
||||||
p->NumFolders = 0;
|
p->NumFolders = 0;
|
||||||
p->NumFiles = 0;
|
p->NumFiles = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
|
void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
if (p->Folders)
|
if (p->Folders)
|
||||||
for (i = 0; i < p->NumFolders; i++)
|
for (i = 0; i < p->NumFolders; i++)
|
||||||
SzFolder_Free(&p->Folders[i], alloc);
|
SzFolder_Free(&p->Folders[i], alloc);
|
||||||
if (p->Files)
|
if (p->Files)
|
||||||
for (i = 0; i < p->NumFiles; i++)
|
for (i = 0; i < p->NumFiles; i++)
|
||||||
SzFile_Free(&p->Files[i], alloc);
|
SzFile_Free(&p->Files[i], alloc);
|
||||||
IAlloc_Free(alloc, p->PackSizes);
|
IAlloc_Free(alloc, p->PackSizes);
|
||||||
IAlloc_Free(alloc, p->PackCRCsDefined);
|
IAlloc_Free(alloc, p->PackCRCsDefined);
|
||||||
IAlloc_Free(alloc, p->PackCRCs);
|
IAlloc_Free(alloc, p->PackCRCs);
|
||||||
IAlloc_Free(alloc, p->Folders);
|
IAlloc_Free(alloc, p->Folders);
|
||||||
IAlloc_Free(alloc, p->Files);
|
IAlloc_Free(alloc, p->Files);
|
||||||
SzAr_Init(p);
|
SzAr_Init(p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,83 +1,83 @@
|
||||||
/* 7zItem.h -- 7z Items
|
/* 7zItem.h -- 7z Items
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
2008-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_ITEM_H
|
#ifndef __7Z_ITEM_H
|
||||||
#define __7Z_ITEM_H
|
#define __7Z_ITEM_H
|
||||||
|
|
||||||
#include "7zBuf.h"
|
#include "7zBuf.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UInt32 NumInStreams;
|
UInt32 NumInStreams;
|
||||||
UInt32 NumOutStreams;
|
UInt32 NumOutStreams;
|
||||||
UInt64 MethodID;
|
UInt64 MethodID;
|
||||||
CBuf Props;
|
CBuf Props;
|
||||||
} CSzCoderInfo;
|
} CSzCoderInfo;
|
||||||
|
|
||||||
void SzCoderInfo_Init(CSzCoderInfo *p);
|
void SzCoderInfo_Init(CSzCoderInfo *p);
|
||||||
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
|
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UInt32 InIndex;
|
UInt32 InIndex;
|
||||||
UInt32 OutIndex;
|
UInt32 OutIndex;
|
||||||
} CBindPair;
|
} CBindPair;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CSzCoderInfo *Coders;
|
CSzCoderInfo *Coders;
|
||||||
CBindPair *BindPairs;
|
CBindPair *BindPairs;
|
||||||
UInt32 *PackStreams;
|
UInt32 *PackStreams;
|
||||||
UInt64 *UnpackSizes;
|
UInt64 *UnpackSizes;
|
||||||
UInt32 NumCoders;
|
UInt32 NumCoders;
|
||||||
UInt32 NumBindPairs;
|
UInt32 NumBindPairs;
|
||||||
UInt32 NumPackStreams;
|
UInt32 NumPackStreams;
|
||||||
int UnpackCRCDefined;
|
int UnpackCRCDefined;
|
||||||
UInt32 UnpackCRC;
|
UInt32 UnpackCRC;
|
||||||
|
|
||||||
UInt32 NumUnpackStreams;
|
UInt32 NumUnpackStreams;
|
||||||
} CSzFolder;
|
} CSzFolder;
|
||||||
|
|
||||||
void SzFolder_Init(CSzFolder *p);
|
void SzFolder_Init(CSzFolder *p);
|
||||||
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
||||||
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
|
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
|
||||||
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
|
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UInt32 Low;
|
UInt32 Low;
|
||||||
UInt32 High;
|
UInt32 High;
|
||||||
} CNtfsFileTime;
|
} CNtfsFileTime;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CNtfsFileTime MTime;
|
CNtfsFileTime MTime;
|
||||||
UInt64 Size;
|
UInt64 Size;
|
||||||
char *Name;
|
char *Name;
|
||||||
UInt32 FileCRC;
|
UInt32 FileCRC;
|
||||||
|
|
||||||
Byte HasStream;
|
Byte HasStream;
|
||||||
Byte IsDir;
|
Byte IsDir;
|
||||||
Byte IsAnti;
|
Byte IsAnti;
|
||||||
Byte FileCRCDefined;
|
Byte FileCRCDefined;
|
||||||
Byte MTimeDefined;
|
Byte MTimeDefined;
|
||||||
} CSzFileItem;
|
} CSzFileItem;
|
||||||
|
|
||||||
void SzFile_Init(CSzFileItem *p);
|
void SzFile_Init(CSzFileItem *p);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UInt64 *PackSizes;
|
UInt64 *PackSizes;
|
||||||
Byte *PackCRCsDefined;
|
Byte *PackCRCsDefined;
|
||||||
UInt32 *PackCRCs;
|
UInt32 *PackCRCs;
|
||||||
CSzFolder *Folders;
|
CSzFolder *Folders;
|
||||||
CSzFileItem *Files;
|
CSzFileItem *Files;
|
||||||
UInt32 NumPackStreams;
|
UInt32 NumPackStreams;
|
||||||
UInt32 NumFolders;
|
UInt32 NumFolders;
|
||||||
UInt32 NumFiles;
|
UInt32 NumFiles;
|
||||||
} CSzAr;
|
} CSzAr;
|
||||||
|
|
||||||
void SzAr_Init(CSzAr *p);
|
void SzAr_Init(CSzAr *p);
|
||||||
void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
|
void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,169 +1,169 @@
|
||||||
/* 7zStream.c -- 7z Stream functions
|
/* 7zStream.c -- 7z Stream functions
|
||||||
2010-03-11 : Igor Pavlov : Public domain */
|
2010-03-11 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
|
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
|
||||||
{
|
{
|
||||||
while (size != 0)
|
while (size != 0)
|
||||||
{
|
{
|
||||||
size_t processed = size;
|
size_t processed = size;
|
||||||
RINOK(stream->Read(stream, buf, &processed));
|
RINOK(stream->Read(stream, buf, &processed));
|
||||||
if (processed == 0)
|
if (processed == 0)
|
||||||
return errorType;
|
return errorType;
|
||||||
buf = (void *)((Byte *)buf + processed);
|
buf = (void *)((Byte *)buf + processed);
|
||||||
size -= processed;
|
size -= processed;
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
|
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
|
||||||
{
|
{
|
||||||
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
|
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
|
||||||
{
|
{
|
||||||
size_t processed = 1;
|
size_t processed = 1;
|
||||||
RINOK(stream->Read(stream, buf, &processed));
|
RINOK(stream->Read(stream, buf, &processed));
|
||||||
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
|
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
|
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
|
||||||
{
|
{
|
||||||
Int64 t = offset;
|
Int64 t = offset;
|
||||||
return stream->Seek(stream, &t, SZ_SEEK_SET);
|
return stream->Seek(stream, &t, SZ_SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
|
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
|
||||||
{
|
{
|
||||||
const void *lookBuf;
|
const void *lookBuf;
|
||||||
if (*size == 0)
|
if (*size == 0)
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
RINOK(stream->Look(stream, &lookBuf, size));
|
RINOK(stream->Look(stream, &lookBuf, size));
|
||||||
memcpy(buf, lookBuf, *size);
|
memcpy(buf, lookBuf, *size);
|
||||||
return stream->Skip(stream, *size);
|
return stream->Skip(stream, *size);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
|
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
|
||||||
{
|
{
|
||||||
while (size != 0)
|
while (size != 0)
|
||||||
{
|
{
|
||||||
size_t processed = size;
|
size_t processed = size;
|
||||||
RINOK(stream->Read(stream, buf, &processed));
|
RINOK(stream->Read(stream, buf, &processed));
|
||||||
if (processed == 0)
|
if (processed == 0)
|
||||||
return errorType;
|
return errorType;
|
||||||
buf = (void *)((Byte *)buf + processed);
|
buf = (void *)((Byte *)buf + processed);
|
||||||
size -= processed;
|
size -= processed;
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
|
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
|
||||||
{
|
{
|
||||||
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
|
static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
|
||||||
{
|
{
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
CLookToRead *p = (CLookToRead *)pp;
|
CLookToRead *p = (CLookToRead *)pp;
|
||||||
size_t size2 = p->size - p->pos;
|
size_t size2 = p->size - p->pos;
|
||||||
if (size2 == 0 && *size > 0)
|
if (size2 == 0 && *size > 0)
|
||||||
{
|
{
|
||||||
p->pos = 0;
|
p->pos = 0;
|
||||||
size2 = LookToRead_BUF_SIZE;
|
size2 = LookToRead_BUF_SIZE;
|
||||||
res = p->realStream->Read(p->realStream, p->buf, &size2);
|
res = p->realStream->Read(p->realStream, p->buf, &size2);
|
||||||
p->size = size2;
|
p->size = size2;
|
||||||
}
|
}
|
||||||
if (size2 < *size)
|
if (size2 < *size)
|
||||||
*size = size2;
|
*size = size2;
|
||||||
*buf = p->buf + p->pos;
|
*buf = p->buf + p->pos;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size)
|
static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size)
|
||||||
{
|
{
|
||||||
SRes res = SZ_OK;
|
SRes res = SZ_OK;
|
||||||
CLookToRead *p = (CLookToRead *)pp;
|
CLookToRead *p = (CLookToRead *)pp;
|
||||||
size_t size2 = p->size - p->pos;
|
size_t size2 = p->size - p->pos;
|
||||||
if (size2 == 0 && *size > 0)
|
if (size2 == 0 && *size > 0)
|
||||||
{
|
{
|
||||||
p->pos = 0;
|
p->pos = 0;
|
||||||
if (*size > LookToRead_BUF_SIZE)
|
if (*size > LookToRead_BUF_SIZE)
|
||||||
*size = LookToRead_BUF_SIZE;
|
*size = LookToRead_BUF_SIZE;
|
||||||
res = p->realStream->Read(p->realStream, p->buf, size);
|
res = p->realStream->Read(p->realStream, p->buf, size);
|
||||||
size2 = p->size = *size;
|
size2 = p->size = *size;
|
||||||
}
|
}
|
||||||
if (size2 < *size)
|
if (size2 < *size)
|
||||||
*size = size2;
|
*size = size2;
|
||||||
*buf = p->buf + p->pos;
|
*buf = p->buf + p->pos;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes LookToRead_Skip(void *pp, size_t offset)
|
static SRes LookToRead_Skip(void *pp, size_t offset)
|
||||||
{
|
{
|
||||||
CLookToRead *p = (CLookToRead *)pp;
|
CLookToRead *p = (CLookToRead *)pp;
|
||||||
p->pos += offset;
|
p->pos += offset;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
|
static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
|
||||||
{
|
{
|
||||||
CLookToRead *p = (CLookToRead *)pp;
|
CLookToRead *p = (CLookToRead *)pp;
|
||||||
size_t rem = p->size - p->pos;
|
size_t rem = p->size - p->pos;
|
||||||
if (rem == 0)
|
if (rem == 0)
|
||||||
return p->realStream->Read(p->realStream, buf, size);
|
return p->realStream->Read(p->realStream, buf, size);
|
||||||
if (rem > *size)
|
if (rem > *size)
|
||||||
rem = *size;
|
rem = *size;
|
||||||
memcpy(buf, p->buf + p->pos, rem);
|
memcpy(buf, p->buf + p->pos, rem);
|
||||||
p->pos += rem;
|
p->pos += rem;
|
||||||
*size = rem;
|
*size = rem;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
|
static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
|
||||||
{
|
{
|
||||||
CLookToRead *p = (CLookToRead *)pp;
|
CLookToRead *p = (CLookToRead *)pp;
|
||||||
p->pos = p->size = 0;
|
p->pos = p->size = 0;
|
||||||
return p->realStream->Seek(p->realStream, pos, origin);
|
return p->realStream->Seek(p->realStream, pos, origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
|
void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
|
||||||
{
|
{
|
||||||
p->s.Look = lookahead ?
|
p->s.Look = lookahead ?
|
||||||
LookToRead_Look_Lookahead :
|
LookToRead_Look_Lookahead :
|
||||||
LookToRead_Look_Exact;
|
LookToRead_Look_Exact;
|
||||||
p->s.Skip = LookToRead_Skip;
|
p->s.Skip = LookToRead_Skip;
|
||||||
p->s.Read = LookToRead_Read;
|
p->s.Read = LookToRead_Read;
|
||||||
p->s.Seek = LookToRead_Seek;
|
p->s.Seek = LookToRead_Seek;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LookToRead_Init(CLookToRead *p)
|
void LookToRead_Init(CLookToRead *p)
|
||||||
{
|
{
|
||||||
p->pos = p->size = 0;
|
p->pos = p->size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
|
static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
|
||||||
{
|
{
|
||||||
CSecToLook *p = (CSecToLook *)pp;
|
CSecToLook *p = (CSecToLook *)pp;
|
||||||
return LookInStream_LookRead(p->realStream, buf, size);
|
return LookInStream_LookRead(p->realStream, buf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecToLook_CreateVTable(CSecToLook *p)
|
void SecToLook_CreateVTable(CSecToLook *p)
|
||||||
{
|
{
|
||||||
p->s.Read = SecToLook_Read;
|
p->s.Read = SecToLook_Read;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
|
static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
|
||||||
{
|
{
|
||||||
CSecToRead *p = (CSecToRead *)pp;
|
CSecToRead *p = (CSecToRead *)pp;
|
||||||
return p->realStream->Read(p->realStream, buf, size);
|
return p->realStream->Read(p->realStream, buf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecToRead_CreateVTable(CSecToRead *p)
|
void SecToRead_CreateVTable(CSecToRead *p)
|
||||||
{
|
{
|
||||||
p->s.Read = SecToRead_Read;
|
p->s.Read = SecToRead_Read;
|
||||||
}
|
}
|
||||||
|
|
264
fex/7z_C/Bcj2.c
264
fex/7z_C/Bcj2.c
|
@ -1,132 +1,132 @@
|
||||||
/* Bcj2.c -- Converter for x86 code (BCJ2)
|
/* Bcj2.c -- Converter for x86 code (BCJ2)
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
2008-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Bcj2.h"
|
#include "Bcj2.h"
|
||||||
|
|
||||||
#ifdef _LZMA_PROB32
|
#ifdef _LZMA_PROB32
|
||||||
#define CProb UInt32
|
#define CProb UInt32
|
||||||
#else
|
#else
|
||||||
#define CProb UInt16
|
#define CProb UInt16
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
|
#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
|
||||||
#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
|
#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
|
||||||
|
|
||||||
#define kNumTopBits 24
|
#define kNumTopBits 24
|
||||||
#define kTopValue ((UInt32)1 << kNumTopBits)
|
#define kTopValue ((UInt32)1 << kNumTopBits)
|
||||||
|
|
||||||
#define kNumBitModelTotalBits 11
|
#define kNumBitModelTotalBits 11
|
||||||
#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
||||||
#define kNumMoveBits 5
|
#define kNumMoveBits 5
|
||||||
|
|
||||||
#define RC_READ_BYTE (*buffer++)
|
#define RC_READ_BYTE (*buffer++)
|
||||||
#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
|
#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
|
||||||
#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \
|
#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \
|
||||||
{ int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}
|
{ int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}
|
||||||
|
|
||||||
#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
|
#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
|
||||||
|
|
||||||
#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
|
#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
|
||||||
#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
|
#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
|
||||||
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
|
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
|
||||||
|
|
||||||
int Bcj2_Decode(
|
int Bcj2_Decode(
|
||||||
const Byte *buf0, SizeT size0,
|
const Byte *buf0, SizeT size0,
|
||||||
const Byte *buf1, SizeT size1,
|
const Byte *buf1, SizeT size1,
|
||||||
const Byte *buf2, SizeT size2,
|
const Byte *buf2, SizeT size2,
|
||||||
const Byte *buf3, SizeT size3,
|
const Byte *buf3, SizeT size3,
|
||||||
Byte *outBuf, SizeT outSize)
|
Byte *outBuf, SizeT outSize)
|
||||||
{
|
{
|
||||||
CProb p[256 + 2];
|
CProb p[256 + 2];
|
||||||
SizeT inPos = 0, outPos = 0;
|
SizeT inPos = 0, outPos = 0;
|
||||||
|
|
||||||
const Byte *buffer, *bufferLim;
|
const Byte *buffer, *bufferLim;
|
||||||
UInt32 range, code;
|
UInt32 range, code;
|
||||||
Byte prevByte = 0;
|
Byte prevByte = 0;
|
||||||
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
|
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
|
||||||
p[i] = kBitModelTotal >> 1;
|
p[i] = kBitModelTotal >> 1;
|
||||||
|
|
||||||
buffer = buf3;
|
buffer = buf3;
|
||||||
bufferLim = buffer + size3;
|
bufferLim = buffer + size3;
|
||||||
RC_INIT2
|
RC_INIT2
|
||||||
|
|
||||||
if (outSize == 0)
|
if (outSize == 0)
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Byte b;
|
Byte b;
|
||||||
CProb *prob;
|
CProb *prob;
|
||||||
UInt32 bound;
|
UInt32 bound;
|
||||||
UInt32 ttt;
|
UInt32 ttt;
|
||||||
|
|
||||||
SizeT limit = size0 - inPos;
|
SizeT limit = size0 - inPos;
|
||||||
if (outSize - outPos < limit)
|
if (outSize - outPos < limit)
|
||||||
limit = outSize - outPos;
|
limit = outSize - outPos;
|
||||||
while (limit != 0)
|
while (limit != 0)
|
||||||
{
|
{
|
||||||
Byte b = buf0[inPos];
|
Byte b = buf0[inPos];
|
||||||
outBuf[outPos++] = b;
|
outBuf[outPos++] = b;
|
||||||
if (IsJ(prevByte, b))
|
if (IsJ(prevByte, b))
|
||||||
break;
|
break;
|
||||||
inPos++;
|
inPos++;
|
||||||
prevByte = b;
|
prevByte = b;
|
||||||
limit--;
|
limit--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (limit == 0 || outPos == outSize)
|
if (limit == 0 || outPos == outSize)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
b = buf0[inPos++];
|
b = buf0[inPos++];
|
||||||
|
|
||||||
if (b == 0xE8)
|
if (b == 0xE8)
|
||||||
prob = p + prevByte;
|
prob = p + prevByte;
|
||||||
else if (b == 0xE9)
|
else if (b == 0xE9)
|
||||||
prob = p + 256;
|
prob = p + 256;
|
||||||
else
|
else
|
||||||
prob = p + 257;
|
prob = p + 257;
|
||||||
|
|
||||||
IF_BIT_0(prob)
|
IF_BIT_0(prob)
|
||||||
{
|
{
|
||||||
UPDATE_0(prob)
|
UPDATE_0(prob)
|
||||||
prevByte = b;
|
prevByte = b;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UInt32 dest;
|
UInt32 dest;
|
||||||
const Byte *v;
|
const Byte *v;
|
||||||
UPDATE_1(prob)
|
UPDATE_1(prob)
|
||||||
if (b == 0xE8)
|
if (b == 0xE8)
|
||||||
{
|
{
|
||||||
v = buf1;
|
v = buf1;
|
||||||
if (size1 < 4)
|
if (size1 < 4)
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
buf1 += 4;
|
buf1 += 4;
|
||||||
size1 -= 4;
|
size1 -= 4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
v = buf2;
|
v = buf2;
|
||||||
if (size2 < 4)
|
if (size2 < 4)
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
buf2 += 4;
|
buf2 += 4;
|
||||||
size2 -= 4;
|
size2 -= 4;
|
||||||
}
|
}
|
||||||
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
|
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
|
||||||
((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
|
((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
|
||||||
outBuf[outPos++] = (Byte)dest;
|
outBuf[outPos++] = (Byte)dest;
|
||||||
if (outPos == outSize)
|
if (outPos == outSize)
|
||||||
break;
|
break;
|
||||||
outBuf[outPos++] = (Byte)(dest >> 8);
|
outBuf[outPos++] = (Byte)(dest >> 8);
|
||||||
if (outPos == outSize)
|
if (outPos == outSize)
|
||||||
break;
|
break;
|
||||||
outBuf[outPos++] = (Byte)(dest >> 16);
|
outBuf[outPos++] = (Byte)(dest >> 16);
|
||||||
if (outPos == outSize)
|
if (outPos == outSize)
|
||||||
break;
|
break;
|
||||||
outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
|
outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
|
return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +1,38 @@
|
||||||
/* Bcj2.h -- Converter for x86 code (BCJ2)
|
/* Bcj2.h -- Converter for x86 code (BCJ2)
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
2009-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __BCJ2_H
|
#ifndef __BCJ2_H
|
||||||
#define __BCJ2_H
|
#define __BCJ2_H
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Conditions:
|
Conditions:
|
||||||
outSize <= FullOutputSize,
|
outSize <= FullOutputSize,
|
||||||
where FullOutputSize is full size of output stream of x86_2 filter.
|
where FullOutputSize is full size of output stream of x86_2 filter.
|
||||||
|
|
||||||
If buf0 overlaps outBuf, there are two required conditions:
|
If buf0 overlaps outBuf, there are two required conditions:
|
||||||
1) (buf0 >= outBuf)
|
1) (buf0 >= outBuf)
|
||||||
2) (buf0 + size0 >= outBuf + FullOutputSize).
|
2) (buf0 + size0 >= outBuf + FullOutputSize).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
SZ_OK
|
SZ_OK
|
||||||
SZ_ERROR_DATA - Data error
|
SZ_ERROR_DATA - Data error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Bcj2_Decode(
|
int Bcj2_Decode(
|
||||||
const Byte *buf0, SizeT size0,
|
const Byte *buf0, SizeT size0,
|
||||||
const Byte *buf1, SizeT size1,
|
const Byte *buf1, SizeT size1,
|
||||||
const Byte *buf2, SizeT size2,
|
const Byte *buf2, SizeT size2,
|
||||||
const Byte *buf3, SizeT size3,
|
const Byte *buf3, SizeT size3,
|
||||||
Byte *outBuf, SizeT outSize);
|
Byte *outBuf, SizeT outSize);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
266
fex/7z_C/Bra.c
266
fex/7z_C/Bra.c
|
@ -1,133 +1,133 @@
|
||||||
/* Bra.c -- Converters for RISC code
|
/* Bra.c -- Converters for RISC code
|
||||||
2010-04-16 : Igor Pavlov : Public domain */
|
2010-04-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Bra.h"
|
#include "Bra.h"
|
||||||
|
|
||||||
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
{
|
{
|
||||||
SizeT i;
|
SizeT i;
|
||||||
if (size < 4)
|
if (size < 4)
|
||||||
return 0;
|
return 0;
|
||||||
size -= 4;
|
size -= 4;
|
||||||
ip += 8;
|
ip += 8;
|
||||||
for (i = 0; i <= size; i += 4)
|
for (i = 0; i <= size; i += 4)
|
||||||
{
|
{
|
||||||
if (data[i + 3] == 0xEB)
|
if (data[i + 3] == 0xEB)
|
||||||
{
|
{
|
||||||
UInt32 dest;
|
UInt32 dest;
|
||||||
UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
|
UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
|
||||||
src <<= 2;
|
src <<= 2;
|
||||||
if (encoding)
|
if (encoding)
|
||||||
dest = ip + (UInt32)i + src;
|
dest = ip + (UInt32)i + src;
|
||||||
else
|
else
|
||||||
dest = src - (ip + (UInt32)i);
|
dest = src - (ip + (UInt32)i);
|
||||||
dest >>= 2;
|
dest >>= 2;
|
||||||
data[i + 2] = (Byte)(dest >> 16);
|
data[i + 2] = (Byte)(dest >> 16);
|
||||||
data[i + 1] = (Byte)(dest >> 8);
|
data[i + 1] = (Byte)(dest >> 8);
|
||||||
data[i + 0] = (Byte)dest;
|
data[i + 0] = (Byte)dest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
{
|
{
|
||||||
SizeT i;
|
SizeT i;
|
||||||
if (size < 4)
|
if (size < 4)
|
||||||
return 0;
|
return 0;
|
||||||
size -= 4;
|
size -= 4;
|
||||||
ip += 4;
|
ip += 4;
|
||||||
for (i = 0; i <= size; i += 2)
|
for (i = 0; i <= size; i += 2)
|
||||||
{
|
{
|
||||||
if ((data[i + 1] & 0xF8) == 0xF0 &&
|
if ((data[i + 1] & 0xF8) == 0xF0 &&
|
||||||
(data[i + 3] & 0xF8) == 0xF8)
|
(data[i + 3] & 0xF8) == 0xF8)
|
||||||
{
|
{
|
||||||
UInt32 dest;
|
UInt32 dest;
|
||||||
UInt32 src =
|
UInt32 src =
|
||||||
(((UInt32)data[i + 1] & 0x7) << 19) |
|
(((UInt32)data[i + 1] & 0x7) << 19) |
|
||||||
((UInt32)data[i + 0] << 11) |
|
((UInt32)data[i + 0] << 11) |
|
||||||
(((UInt32)data[i + 3] & 0x7) << 8) |
|
(((UInt32)data[i + 3] & 0x7) << 8) |
|
||||||
(data[i + 2]);
|
(data[i + 2]);
|
||||||
|
|
||||||
src <<= 1;
|
src <<= 1;
|
||||||
if (encoding)
|
if (encoding)
|
||||||
dest = ip + (UInt32)i + src;
|
dest = ip + (UInt32)i + src;
|
||||||
else
|
else
|
||||||
dest = src - (ip + (UInt32)i);
|
dest = src - (ip + (UInt32)i);
|
||||||
dest >>= 1;
|
dest >>= 1;
|
||||||
|
|
||||||
data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
|
data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
|
||||||
data[i + 0] = (Byte)(dest >> 11);
|
data[i + 0] = (Byte)(dest >> 11);
|
||||||
data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
|
data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
|
||||||
data[i + 2] = (Byte)dest;
|
data[i + 2] = (Byte)dest;
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
{
|
{
|
||||||
SizeT i;
|
SizeT i;
|
||||||
if (size < 4)
|
if (size < 4)
|
||||||
return 0;
|
return 0;
|
||||||
size -= 4;
|
size -= 4;
|
||||||
for (i = 0; i <= size; i += 4)
|
for (i = 0; i <= size; i += 4)
|
||||||
{
|
{
|
||||||
if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
|
if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
|
||||||
{
|
{
|
||||||
UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
|
UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
|
||||||
((UInt32)data[i + 1] << 16) |
|
((UInt32)data[i + 1] << 16) |
|
||||||
((UInt32)data[i + 2] << 8) |
|
((UInt32)data[i + 2] << 8) |
|
||||||
((UInt32)data[i + 3] & (~3));
|
((UInt32)data[i + 3] & (~3));
|
||||||
|
|
||||||
UInt32 dest;
|
UInt32 dest;
|
||||||
if (encoding)
|
if (encoding)
|
||||||
dest = ip + (UInt32)i + src;
|
dest = ip + (UInt32)i + src;
|
||||||
else
|
else
|
||||||
dest = src - (ip + (UInt32)i);
|
dest = src - (ip + (UInt32)i);
|
||||||
data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3));
|
data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3));
|
||||||
data[i + 1] = (Byte)(dest >> 16);
|
data[i + 1] = (Byte)(dest >> 16);
|
||||||
data[i + 2] = (Byte)(dest >> 8);
|
data[i + 2] = (Byte)(dest >> 8);
|
||||||
data[i + 3] &= 0x3;
|
data[i + 3] &= 0x3;
|
||||||
data[i + 3] |= dest;
|
data[i + 3] |= dest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
if (size < 4)
|
if (size < 4)
|
||||||
return 0;
|
return 0;
|
||||||
size -= 4;
|
size -= 4;
|
||||||
for (i = 0; i <= size; i += 4)
|
for (i = 0; i <= size; i += 4)
|
||||||
{
|
{
|
||||||
if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
|
if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
|
||||||
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
|
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
|
||||||
{
|
{
|
||||||
UInt32 src =
|
UInt32 src =
|
||||||
((UInt32)data[i + 0] << 24) |
|
((UInt32)data[i + 0] << 24) |
|
||||||
((UInt32)data[i + 1] << 16) |
|
((UInt32)data[i + 1] << 16) |
|
||||||
((UInt32)data[i + 2] << 8) |
|
((UInt32)data[i + 2] << 8) |
|
||||||
((UInt32)data[i + 3]);
|
((UInt32)data[i + 3]);
|
||||||
UInt32 dest;
|
UInt32 dest;
|
||||||
|
|
||||||
src <<= 2;
|
src <<= 2;
|
||||||
if (encoding)
|
if (encoding)
|
||||||
dest = ip + i + src;
|
dest = ip + i + src;
|
||||||
else
|
else
|
||||||
dest = src - (ip + i);
|
dest = src - (ip + i);
|
||||||
dest >>= 2;
|
dest >>= 2;
|
||||||
|
|
||||||
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
|
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
|
||||||
|
|
||||||
data[i + 0] = (Byte)(dest >> 24);
|
data[i + 0] = (Byte)(dest >> 24);
|
||||||
data[i + 1] = (Byte)(dest >> 16);
|
data[i + 1] = (Byte)(dest >> 16);
|
||||||
data[i + 2] = (Byte)(dest >> 8);
|
data[i + 2] = (Byte)(dest >> 8);
|
||||||
data[i + 3] = (Byte)dest;
|
data[i + 3] = (Byte)dest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
136
fex/7z_C/Bra.h
136
fex/7z_C/Bra.h
|
@ -1,68 +1,68 @@
|
||||||
/* Bra.h -- Branch converters for executables
|
/* Bra.h -- Branch converters for executables
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
2009-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __BRA_H
|
#ifndef __BRA_H
|
||||||
#define __BRA_H
|
#define __BRA_H
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
These functions convert relative addresses to absolute addresses
|
These functions convert relative addresses to absolute addresses
|
||||||
in CALL instructions to increase the compression ratio.
|
in CALL instructions to increase the compression ratio.
|
||||||
|
|
||||||
In:
|
In:
|
||||||
data - data buffer
|
data - data buffer
|
||||||
size - size of data
|
size - size of data
|
||||||
ip - current virtual Instruction Pinter (IP) value
|
ip - current virtual Instruction Pinter (IP) value
|
||||||
state - state variable for x86 converter
|
state - state variable for x86 converter
|
||||||
encoding - 0 (for decoding), 1 (for encoding)
|
encoding - 0 (for decoding), 1 (for encoding)
|
||||||
|
|
||||||
Out:
|
Out:
|
||||||
state - state variable for x86 converter
|
state - state variable for x86 converter
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The number of processed bytes. If you call these functions with multiple calls,
|
The number of processed bytes. If you call these functions with multiple calls,
|
||||||
you must start next call with first byte after block of processed bytes.
|
you must start next call with first byte after block of processed bytes.
|
||||||
|
|
||||||
Type Endian Alignment LookAhead
|
Type Endian Alignment LookAhead
|
||||||
|
|
||||||
x86 little 1 4
|
x86 little 1 4
|
||||||
ARMT little 2 2
|
ARMT little 2 2
|
||||||
ARM little 4 0
|
ARM little 4 0
|
||||||
PPC big 4 0
|
PPC big 4 0
|
||||||
SPARC big 4 0
|
SPARC big 4 0
|
||||||
IA64 little 16 0
|
IA64 little 16 0
|
||||||
|
|
||||||
size must be >= Alignment + LookAhead, if it's not last block.
|
size must be >= Alignment + LookAhead, if it's not last block.
|
||||||
If (size < Alignment + LookAhead), converter returns 0.
|
If (size < Alignment + LookAhead), converter returns 0.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
UInt32 ip = 0;
|
UInt32 ip = 0;
|
||||||
for ()
|
for ()
|
||||||
{
|
{
|
||||||
; size must be >= Alignment + LookAhead, if it's not last block
|
; size must be >= Alignment + LookAhead, if it's not last block
|
||||||
SizeT processed = Convert(data, size, ip, 1);
|
SizeT processed = Convert(data, size, ip, 1);
|
||||||
data += processed;
|
data += processed;
|
||||||
size -= processed;
|
size -= processed;
|
||||||
ip += processed;
|
ip += processed;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define x86_Convert_Init(state) { state = 0; }
|
#define x86_Convert_Init(state) { state = 0; }
|
||||||
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
|
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
|
||||||
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
170
fex/7z_C/Bra86.c
170
fex/7z_C/Bra86.c
|
@ -1,85 +1,85 @@
|
||||||
/* Bra86.c -- Converter for x86 code (BCJ)
|
/* Bra86.c -- Converter for x86 code (BCJ)
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
2008-10-04 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Bra.h"
|
#include "Bra.h"
|
||||||
|
|
||||||
#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
|
#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
|
||||||
|
|
||||||
const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
|
const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
|
||||||
const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
|
const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
|
||||||
|
|
||||||
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
|
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
|
||||||
{
|
{
|
||||||
SizeT bufferPos = 0, prevPosT;
|
SizeT bufferPos = 0, prevPosT;
|
||||||
UInt32 prevMask = *state & 0x7;
|
UInt32 prevMask = *state & 0x7;
|
||||||
if (size < 5)
|
if (size < 5)
|
||||||
return 0;
|
return 0;
|
||||||
ip += 5;
|
ip += 5;
|
||||||
prevPosT = (SizeT)0 - 1;
|
prevPosT = (SizeT)0 - 1;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Byte *p = data + bufferPos;
|
Byte *p = data + bufferPos;
|
||||||
Byte *limit = data + size - 4;
|
Byte *limit = data + size - 4;
|
||||||
for (; p < limit; p++)
|
for (; p < limit; p++)
|
||||||
if ((*p & 0xFE) == 0xE8)
|
if ((*p & 0xFE) == 0xE8)
|
||||||
break;
|
break;
|
||||||
bufferPos = (SizeT)(p - data);
|
bufferPos = (SizeT)(p - data);
|
||||||
if (p >= limit)
|
if (p >= limit)
|
||||||
break;
|
break;
|
||||||
prevPosT = bufferPos - prevPosT;
|
prevPosT = bufferPos - prevPosT;
|
||||||
if (prevPosT > 3)
|
if (prevPosT > 3)
|
||||||
prevMask = 0;
|
prevMask = 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
|
prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
|
||||||
if (prevMask != 0)
|
if (prevMask != 0)
|
||||||
{
|
{
|
||||||
Byte b = p[4 - kMaskToBitNumber[prevMask]];
|
Byte b = p[4 - kMaskToBitNumber[prevMask]];
|
||||||
if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
|
if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
|
||||||
{
|
{
|
||||||
prevPosT = bufferPos;
|
prevPosT = bufferPos;
|
||||||
prevMask = ((prevMask << 1) & 0x7) | 1;
|
prevMask = ((prevMask << 1) & 0x7) | 1;
|
||||||
bufferPos++;
|
bufferPos++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prevPosT = bufferPos;
|
prevPosT = bufferPos;
|
||||||
|
|
||||||
if (Test86MSByte(p[4]))
|
if (Test86MSByte(p[4]))
|
||||||
{
|
{
|
||||||
UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
|
UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
|
||||||
UInt32 dest;
|
UInt32 dest;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Byte b;
|
Byte b;
|
||||||
int index;
|
int index;
|
||||||
if (encoding)
|
if (encoding)
|
||||||
dest = (ip + (UInt32)bufferPos) + src;
|
dest = (ip + (UInt32)bufferPos) + src;
|
||||||
else
|
else
|
||||||
dest = src - (ip + (UInt32)bufferPos);
|
dest = src - (ip + (UInt32)bufferPos);
|
||||||
if (prevMask == 0)
|
if (prevMask == 0)
|
||||||
break;
|
break;
|
||||||
index = kMaskToBitNumber[prevMask] * 8;
|
index = kMaskToBitNumber[prevMask] * 8;
|
||||||
b = (Byte)(dest >> (24 - index));
|
b = (Byte)(dest >> (24 - index));
|
||||||
if (!Test86MSByte(b))
|
if (!Test86MSByte(b))
|
||||||
break;
|
break;
|
||||||
src = dest ^ ((1 << (32 - index)) - 1);
|
src = dest ^ ((1 << (32 - index)) - 1);
|
||||||
}
|
}
|
||||||
p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
|
p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
|
||||||
p[3] = (Byte)(dest >> 16);
|
p[3] = (Byte)(dest >> 16);
|
||||||
p[2] = (Byte)(dest >> 8);
|
p[2] = (Byte)(dest >> 8);
|
||||||
p[1] = (Byte)dest;
|
p[1] = (Byte)dest;
|
||||||
bufferPos += 5;
|
bufferPos += 5;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prevMask = ((prevMask << 1) & 0x7) | 1;
|
prevMask = ((prevMask << 1) & 0x7) | 1;
|
||||||
bufferPos++;
|
bufferPos++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prevPosT = bufferPos - prevPosT;
|
prevPosT = bufferPos - prevPosT;
|
||||||
*state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
|
*state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
|
||||||
return bufferPos;
|
return bufferPos;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,168 +1,168 @@
|
||||||
/* CpuArch.c -- CPU specific code
|
/* CpuArch.c -- CPU specific code
|
||||||
2010-10-26: Igor Pavlov : Public domain */
|
2010-10-26: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
|
|
||||||
#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
|
#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
|
||||||
#define USE_ASM
|
#define USE_ASM
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
|
#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
|
||||||
static UInt32 CheckFlag(UInt32 flag)
|
static UInt32 CheckFlag(UInt32 flag)
|
||||||
{
|
{
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
__asm pushfd;
|
__asm pushfd;
|
||||||
__asm pop EAX;
|
__asm pop EAX;
|
||||||
__asm mov EDX, EAX;
|
__asm mov EDX, EAX;
|
||||||
__asm xor EAX, flag;
|
__asm xor EAX, flag;
|
||||||
__asm push EAX;
|
__asm push EAX;
|
||||||
__asm popfd;
|
__asm popfd;
|
||||||
__asm pushfd;
|
__asm pushfd;
|
||||||
__asm pop EAX;
|
__asm pop EAX;
|
||||||
__asm xor EAX, EDX;
|
__asm xor EAX, EDX;
|
||||||
__asm push EDX;
|
__asm push EDX;
|
||||||
__asm popfd;
|
__asm popfd;
|
||||||
__asm and flag, EAX;
|
__asm and flag, EAX;
|
||||||
#else
|
#else
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
"pushf\n\t"
|
"pushf\n\t"
|
||||||
"pop %%EAX\n\t"
|
"pop %%EAX\n\t"
|
||||||
"movl %%EAX,%%EDX\n\t"
|
"movl %%EAX,%%EDX\n\t"
|
||||||
"xorl %0,%%EAX\n\t"
|
"xorl %0,%%EAX\n\t"
|
||||||
"push %%EAX\n\t"
|
"push %%EAX\n\t"
|
||||||
"popf\n\t"
|
"popf\n\t"
|
||||||
"pushf\n\t"
|
"pushf\n\t"
|
||||||
"pop %%EAX\n\t"
|
"pop %%EAX\n\t"
|
||||||
"xorl %%EDX,%%EAX\n\t"
|
"xorl %%EDX,%%EAX\n\t"
|
||||||
"push %%EDX\n\t"
|
"push %%EDX\n\t"
|
||||||
"popf\n\t"
|
"popf\n\t"
|
||||||
"andl %%EAX, %0\n\t":
|
"andl %%EAX, %0\n\t":
|
||||||
"=c" (flag) : "c" (flag));
|
"=c" (flag) : "c" (flag));
|
||||||
#endif
|
#endif
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
|
#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
|
||||||
#else
|
#else
|
||||||
#define CHECK_CPUID_IS_SUPPORTED
|
#define CHECK_CPUID_IS_SUPPORTED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
|
static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
|
||||||
{
|
{
|
||||||
#ifdef USE_ASM
|
#ifdef USE_ASM
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
UInt32 a2, b2, c2, d2;
|
UInt32 a2, b2, c2, d2;
|
||||||
__asm xor EBX, EBX;
|
__asm xor EBX, EBX;
|
||||||
__asm xor ECX, ECX;
|
__asm xor ECX, ECX;
|
||||||
__asm xor EDX, EDX;
|
__asm xor EDX, EDX;
|
||||||
__asm mov EAX, function;
|
__asm mov EAX, function;
|
||||||
__asm cpuid;
|
__asm cpuid;
|
||||||
__asm mov a2, EAX;
|
__asm mov a2, EAX;
|
||||||
__asm mov b2, EBX;
|
__asm mov b2, EBX;
|
||||||
__asm mov c2, ECX;
|
__asm mov c2, ECX;
|
||||||
__asm mov d2, EDX;
|
__asm mov d2, EDX;
|
||||||
|
|
||||||
*a = a2;
|
*a = a2;
|
||||||
*b = b2;
|
*b = b2;
|
||||||
*c = c2;
|
*c = c2;
|
||||||
*d = d2;
|
*d = d2;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
"cpuid"
|
"cpuid"
|
||||||
: "=a" (*a) ,
|
: "=a" (*a) ,
|
||||||
"=b" (*b) ,
|
"=b" (*b) ,
|
||||||
"=c" (*c) ,
|
"=c" (*c) ,
|
||||||
"=d" (*d)
|
"=d" (*d)
|
||||||
: "0" (function)) ;
|
: "0" (function)) ;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
int CPUInfo[4];
|
int CPUInfo[4];
|
||||||
__cpuid(CPUInfo, function);
|
__cpuid(CPUInfo, function);
|
||||||
*a = CPUInfo[0];
|
*a = CPUInfo[0];
|
||||||
*b = CPUInfo[1];
|
*b = CPUInfo[1];
|
||||||
*c = CPUInfo[2];
|
*c = CPUInfo[2];
|
||||||
*d = CPUInfo[3];
|
*d = CPUInfo[3];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
|
Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
|
||||||
{
|
{
|
||||||
CHECK_CPUID_IS_SUPPORTED
|
CHECK_CPUID_IS_SUPPORTED
|
||||||
MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
|
MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
|
||||||
MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
|
MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UInt32 kVendors[][3] =
|
static UInt32 kVendors[][3] =
|
||||||
{
|
{
|
||||||
{ 0x756E6547, 0x49656E69, 0x6C65746E},
|
{ 0x756E6547, 0x49656E69, 0x6C65746E},
|
||||||
{ 0x68747541, 0x69746E65, 0x444D4163},
|
{ 0x68747541, 0x69746E65, 0x444D4163},
|
||||||
{ 0x746E6543, 0x48727561, 0x736C7561}
|
{ 0x746E6543, 0x48727561, 0x736C7561}
|
||||||
};
|
};
|
||||||
|
|
||||||
int x86cpuid_GetFirm(const Cx86cpuid *p)
|
int x86cpuid_GetFirm(const Cx86cpuid *p)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
|
for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
|
||||||
{
|
{
|
||||||
const UInt32 *v = kVendors[i];
|
const UInt32 *v = kVendors[i];
|
||||||
if (v[0] == p->vendor[0] &&
|
if (v[0] == p->vendor[0] &&
|
||||||
v[1] == p->vendor[1] &&
|
v[1] == p->vendor[1] &&
|
||||||
v[2] == p->vendor[2])
|
v[2] == p->vendor[2])
|
||||||
return (int)i;
|
return (int)i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool CPU_Is_InOrder()
|
Bool CPU_Is_InOrder()
|
||||||
{
|
{
|
||||||
Cx86cpuid p;
|
Cx86cpuid p;
|
||||||
int firm;
|
int firm;
|
||||||
UInt32 family, model;
|
UInt32 family, model;
|
||||||
if (!x86cpuid_CheckAndRead(&p))
|
if (!x86cpuid_CheckAndRead(&p))
|
||||||
return True;
|
return True;
|
||||||
family = x86cpuid_GetFamily(&p);
|
family = x86cpuid_GetFamily(&p);
|
||||||
model = x86cpuid_GetModel(&p);
|
model = x86cpuid_GetModel(&p);
|
||||||
firm = x86cpuid_GetFirm(&p);
|
firm = x86cpuid_GetFirm(&p);
|
||||||
switch (firm)
|
switch (firm)
|
||||||
{
|
{
|
||||||
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C));
|
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C));
|
||||||
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
|
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
|
||||||
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
|
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
|
||||||
}
|
}
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(MY_CPU_AMD64) && defined(_WIN32)
|
#if !defined(MY_CPU_AMD64) && defined(_WIN32)
|
||||||
static Bool CPU_Sys_Is_SSE_Supported()
|
static Bool CPU_Sys_Is_SSE_Supported()
|
||||||
{
|
{
|
||||||
OSVERSIONINFO vi;
|
OSVERSIONINFO vi;
|
||||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||||
if (!GetVersionEx(&vi))
|
if (!GetVersionEx(&vi))
|
||||||
return False;
|
return False;
|
||||||
return (vi.dwMajorVersion >= 5);
|
return (vi.dwMajorVersion >= 5);
|
||||||
}
|
}
|
||||||
#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
|
#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
|
||||||
#else
|
#else
|
||||||
#define CHECK_SYS_SSE_SUPPORT
|
#define CHECK_SYS_SSE_SUPPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Bool CPU_Is_Aes_Supported()
|
Bool CPU_Is_Aes_Supported()
|
||||||
{
|
{
|
||||||
Cx86cpuid p;
|
Cx86cpuid p;
|
||||||
CHECK_SYS_SSE_SUPPORT
|
CHECK_SYS_SSE_SUPPORT
|
||||||
if (!x86cpuid_CheckAndRead(&p))
|
if (!x86cpuid_CheckAndRead(&p))
|
||||||
return False;
|
return False;
|
||||||
return (p.c >> 25) & 1;
|
return (p.c >> 25) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,155 +1,155 @@
|
||||||
/* CpuArch.h -- CPU specific code
|
/* CpuArch.h -- CPU specific code
|
||||||
2010-10-26: Igor Pavlov : Public domain */
|
2010-10-26: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __CPU_ARCH_H
|
#ifndef __CPU_ARCH_H
|
||||||
#define __CPU_ARCH_H
|
#define __CPU_ARCH_H
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
EXTERN_C_BEGIN
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
/*
|
/*
|
||||||
MY_CPU_LE means that CPU is LITTLE ENDIAN.
|
MY_CPU_LE means that CPU is LITTLE ENDIAN.
|
||||||
If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN).
|
If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN).
|
||||||
|
|
||||||
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
|
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
|
||||||
If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform.
|
If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
|
#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
|
||||||
#define MY_CPU_AMD64
|
#define MY_CPU_AMD64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_AMD64) || defined(_M_IA64)
|
#if defined(MY_CPU_AMD64) || defined(_M_IA64)
|
||||||
#define MY_CPU_64BIT
|
#define MY_CPU_64BIT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_M_IX86) || defined(__i386__)
|
#if defined(_M_IX86) || defined(__i386__)
|
||||||
#define MY_CPU_X86
|
#define MY_CPU_X86
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
|
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
|
||||||
#define MY_CPU_X86_OR_AMD64
|
#define MY_CPU_X86_OR_AMD64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_X86) || defined(_M_ARM)
|
#if defined(MY_CPU_X86) || defined(_M_ARM)
|
||||||
#define MY_CPU_32BIT
|
#define MY_CPU_32BIT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(_M_ARM)
|
#if defined(_WIN32) && defined(_M_ARM)
|
||||||
#define MY_CPU_ARM_LE
|
#define MY_CPU_ARM_LE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(_M_IA64)
|
#if defined(_WIN32) && defined(_M_IA64)
|
||||||
#define MY_CPU_IA64_LE
|
#define MY_CPU_IA64_LE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_X86_OR_AMD64)
|
#if defined(MY_CPU_X86_OR_AMD64)
|
||||||
#define MY_CPU_LE_UNALIGN
|
#define MY_CPU_LE_UNALIGN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
|
#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
|
||||||
#define MY_CPU_LE
|
#define MY_CPU_LE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__BIG_ENDIAN__)
|
#if defined(__BIG_ENDIAN__)
|
||||||
#define MY_CPU_BE
|
#define MY_CPU_BE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
|
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
|
||||||
Stop_Compiling_Bad_Endian
|
Stop_Compiling_Bad_Endian
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MY_CPU_LE_UNALIGN
|
#ifdef MY_CPU_LE_UNALIGN
|
||||||
|
|
||||||
#define GetUi16(p) (*(const UInt16 *)(p))
|
#define GetUi16(p) (*(const UInt16 *)(p))
|
||||||
#define GetUi32(p) (*(const UInt32 *)(p))
|
#define GetUi32(p) (*(const UInt32 *)(p))
|
||||||
#define GetUi64(p) (*(const UInt64 *)(p))
|
#define GetUi64(p) (*(const UInt64 *)(p))
|
||||||
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
|
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
|
||||||
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
|
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
|
||||||
#define SetUi64(p, d) *(UInt64 *)(p) = (d);
|
#define SetUi64(p, d) *(UInt64 *)(p) = (d);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
|
#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
|
||||||
|
|
||||||
#define GetUi32(p) ( \
|
#define GetUi32(p) ( \
|
||||||
((const Byte *)(p))[0] | \
|
((const Byte *)(p))[0] | \
|
||||||
((UInt32)((const Byte *)(p))[1] << 8) | \
|
((UInt32)((const Byte *)(p))[1] << 8) | \
|
||||||
((UInt32)((const Byte *)(p))[2] << 16) | \
|
((UInt32)((const Byte *)(p))[2] << 16) | \
|
||||||
((UInt32)((const Byte *)(p))[3] << 24))
|
((UInt32)((const Byte *)(p))[3] << 24))
|
||||||
|
|
||||||
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
|
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
|
||||||
|
|
||||||
#define SetUi16(p, d) { UInt32 _x_ = (d); \
|
#define SetUi16(p, d) { UInt32 _x_ = (d); \
|
||||||
((Byte *)(p))[0] = (Byte)_x_; \
|
((Byte *)(p))[0] = (Byte)_x_; \
|
||||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); }
|
((Byte *)(p))[1] = (Byte)(_x_ >> 8); }
|
||||||
|
|
||||||
#define SetUi32(p, d) { UInt32 _x_ = (d); \
|
#define SetUi32(p, d) { UInt32 _x_ = (d); \
|
||||||
((Byte *)(p))[0] = (Byte)_x_; \
|
((Byte *)(p))[0] = (Byte)_x_; \
|
||||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
|
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
|
||||||
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
|
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
|
||||||
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
|
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
|
||||||
|
|
||||||
#define SetUi64(p, d) { UInt64 _x64_ = (d); \
|
#define SetUi64(p, d) { UInt64 _x64_ = (d); \
|
||||||
SetUi32(p, (UInt32)_x64_); \
|
SetUi32(p, (UInt32)_x64_); \
|
||||||
SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
|
SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
|
#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
|
||||||
|
|
||||||
#pragma intrinsic(_byteswap_ulong)
|
#pragma intrinsic(_byteswap_ulong)
|
||||||
#pragma intrinsic(_byteswap_uint64)
|
#pragma intrinsic(_byteswap_uint64)
|
||||||
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
||||||
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
|
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define GetBe32(p) ( \
|
#define GetBe32(p) ( \
|
||||||
((UInt32)((const Byte *)(p))[0] << 24) | \
|
((UInt32)((const Byte *)(p))[0] << 24) | \
|
||||||
((UInt32)((const Byte *)(p))[1] << 16) | \
|
((UInt32)((const Byte *)(p))[1] << 16) | \
|
||||||
((UInt32)((const Byte *)(p))[2] << 8) | \
|
((UInt32)((const Byte *)(p))[2] << 8) | \
|
||||||
((const Byte *)(p))[3] )
|
((const Byte *)(p))[3] )
|
||||||
|
|
||||||
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
|
#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
|
||||||
|
|
||||||
|
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UInt32 maxFunc;
|
UInt32 maxFunc;
|
||||||
UInt32 vendor[3];
|
UInt32 vendor[3];
|
||||||
UInt32 ver;
|
UInt32 ver;
|
||||||
UInt32 b;
|
UInt32 b;
|
||||||
UInt32 c;
|
UInt32 c;
|
||||||
UInt32 d;
|
UInt32 d;
|
||||||
} Cx86cpuid;
|
} Cx86cpuid;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
CPU_FIRM_INTEL,
|
CPU_FIRM_INTEL,
|
||||||
CPU_FIRM_AMD,
|
CPU_FIRM_AMD,
|
||||||
CPU_FIRM_VIA
|
CPU_FIRM_VIA
|
||||||
};
|
};
|
||||||
|
|
||||||
Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
|
Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
|
||||||
int x86cpuid_GetFirm(const Cx86cpuid *p);
|
int x86cpuid_GetFirm(const Cx86cpuid *p);
|
||||||
|
|
||||||
#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F)
|
#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F)
|
||||||
#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F)
|
#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F)
|
||||||
#define x86cpuid_GetStepping(p) ((p)->ver & 0xF)
|
#define x86cpuid_GetStepping(p) ((p)->ver & 0xF)
|
||||||
|
|
||||||
Bool CPU_Is_InOrder();
|
Bool CPU_Is_InOrder();
|
||||||
Bool CPU_Is_Aes_Supported();
|
Bool CPU_Is_Aes_Supported();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,371 +1,371 @@
|
||||||
/* Lzma2Dec.c -- LZMA2 Decoder
|
/* Lzma2Dec.c -- LZMA2 Decoder
|
||||||
2009-05-03 : Igor Pavlov : Public domain */
|
2009-05-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
/* #define SHOW_DEBUG_INFO */
|
/* #define SHOW_DEBUG_INFO */
|
||||||
|
|
||||||
#ifdef SHOW_DEBUG_INFO
|
#ifdef SHOW_DEBUG_INFO
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "Lzma2Dec.h"
|
#include "Lzma2Dec.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
00000000 - EOS
|
00000000 - EOS
|
||||||
00000001 U U - Uncompressed Reset Dic
|
00000001 U U - Uncompressed Reset Dic
|
||||||
00000010 U U - Uncompressed No Reset
|
00000010 U U - Uncompressed No Reset
|
||||||
100uuuuu U U P P - LZMA no reset
|
100uuuuu U U P P - LZMA no reset
|
||||||
101uuuuu U U P P - LZMA reset state
|
101uuuuu U U P P - LZMA reset state
|
||||||
110uuuuu U U P P S - LZMA reset state + new prop
|
110uuuuu U U P P S - LZMA reset state + new prop
|
||||||
111uuuuu U U P P S - LZMA reset state + new prop + reset dic
|
111uuuuu U U P P S - LZMA reset state + new prop + reset dic
|
||||||
|
|
||||||
u, U - Unpack Size
|
u, U - Unpack Size
|
||||||
P - Pack Size
|
P - Pack Size
|
||||||
S - Props
|
S - Props
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LZMA2_CONTROL_LZMA (1 << 7)
|
#define LZMA2_CONTROL_LZMA (1 << 7)
|
||||||
#define LZMA2_CONTROL_COPY_NO_RESET 2
|
#define LZMA2_CONTROL_COPY_NO_RESET 2
|
||||||
#define LZMA2_CONTROL_COPY_RESET_DIC 1
|
#define LZMA2_CONTROL_COPY_RESET_DIC 1
|
||||||
#define LZMA2_CONTROL_EOF 0
|
#define LZMA2_CONTROL_EOF 0
|
||||||
|
|
||||||
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)
|
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)
|
||||||
|
|
||||||
#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
|
#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
|
||||||
#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
|
#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
|
||||||
|
|
||||||
#define LZMA2_LCLP_MAX 4
|
#define LZMA2_LCLP_MAX 4
|
||||||
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
|
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
|
||||||
|
|
||||||
#ifdef SHOW_DEBUG_INFO
|
#ifdef SHOW_DEBUG_INFO
|
||||||
#define PRF(x) x
|
#define PRF(x) x
|
||||||
#else
|
#else
|
||||||
#define PRF(x)
|
#define PRF(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
LZMA2_STATE_CONTROL,
|
LZMA2_STATE_CONTROL,
|
||||||
LZMA2_STATE_UNPACK0,
|
LZMA2_STATE_UNPACK0,
|
||||||
LZMA2_STATE_UNPACK1,
|
LZMA2_STATE_UNPACK1,
|
||||||
LZMA2_STATE_PACK0,
|
LZMA2_STATE_PACK0,
|
||||||
LZMA2_STATE_PACK1,
|
LZMA2_STATE_PACK1,
|
||||||
LZMA2_STATE_PROP,
|
LZMA2_STATE_PROP,
|
||||||
LZMA2_STATE_DATA,
|
LZMA2_STATE_DATA,
|
||||||
LZMA2_STATE_DATA_CONT,
|
LZMA2_STATE_DATA_CONT,
|
||||||
LZMA2_STATE_FINISHED,
|
LZMA2_STATE_FINISHED,
|
||||||
LZMA2_STATE_ERROR
|
LZMA2_STATE_ERROR
|
||||||
} ELzma2State;
|
} ELzma2State;
|
||||||
|
|
||||||
static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
|
static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
|
||||||
{
|
{
|
||||||
UInt32 dicSize;
|
UInt32 dicSize;
|
||||||
if (prop > 40)
|
if (prop > 40)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
|
dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
|
||||||
props[0] = (Byte)LZMA2_LCLP_MAX;
|
props[0] = (Byte)LZMA2_LCLP_MAX;
|
||||||
props[1] = (Byte)(dicSize);
|
props[1] = (Byte)(dicSize);
|
||||||
props[2] = (Byte)(dicSize >> 8);
|
props[2] = (Byte)(dicSize >> 8);
|
||||||
props[3] = (Byte)(dicSize >> 16);
|
props[3] = (Byte)(dicSize >> 16);
|
||||||
props[4] = (Byte)(dicSize >> 24);
|
props[4] = (Byte)(dicSize >> 24);
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
|
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
Byte props[LZMA_PROPS_SIZE];
|
Byte props[LZMA_PROPS_SIZE];
|
||||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||||
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
|
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
|
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
Byte props[LZMA_PROPS_SIZE];
|
Byte props[LZMA_PROPS_SIZE];
|
||||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||||
return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
|
return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lzma2Dec_Init(CLzma2Dec *p)
|
void Lzma2Dec_Init(CLzma2Dec *p)
|
||||||
{
|
{
|
||||||
p->state = LZMA2_STATE_CONTROL;
|
p->state = LZMA2_STATE_CONTROL;
|
||||||
p->needInitDic = True;
|
p->needInitDic = True;
|
||||||
p->needInitState = True;
|
p->needInitState = True;
|
||||||
p->needInitProp = True;
|
p->needInitProp = True;
|
||||||
LzmaDec_Init(&p->decoder);
|
LzmaDec_Init(&p->decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
|
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
|
||||||
{
|
{
|
||||||
switch(p->state)
|
switch(p->state)
|
||||||
{
|
{
|
||||||
case LZMA2_STATE_CONTROL:
|
case LZMA2_STATE_CONTROL:
|
||||||
p->control = b;
|
p->control = b;
|
||||||
PRF(printf("\n %4X ", p->decoder.dicPos));
|
PRF(printf("\n %4X ", p->decoder.dicPos));
|
||||||
PRF(printf(" %2X", b));
|
PRF(printf(" %2X", b));
|
||||||
if (p->control == 0)
|
if (p->control == 0)
|
||||||
return LZMA2_STATE_FINISHED;
|
return LZMA2_STATE_FINISHED;
|
||||||
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
|
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
|
||||||
{
|
{
|
||||||
if ((p->control & 0x7F) > 2)
|
if ((p->control & 0x7F) > 2)
|
||||||
return LZMA2_STATE_ERROR;
|
return LZMA2_STATE_ERROR;
|
||||||
p->unpackSize = 0;
|
p->unpackSize = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
|
p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
|
||||||
return LZMA2_STATE_UNPACK0;
|
return LZMA2_STATE_UNPACK0;
|
||||||
|
|
||||||
case LZMA2_STATE_UNPACK0:
|
case LZMA2_STATE_UNPACK0:
|
||||||
p->unpackSize |= (UInt32)b << 8;
|
p->unpackSize |= (UInt32)b << 8;
|
||||||
return LZMA2_STATE_UNPACK1;
|
return LZMA2_STATE_UNPACK1;
|
||||||
|
|
||||||
case LZMA2_STATE_UNPACK1:
|
case LZMA2_STATE_UNPACK1:
|
||||||
p->unpackSize |= (UInt32)b;
|
p->unpackSize |= (UInt32)b;
|
||||||
p->unpackSize++;
|
p->unpackSize++;
|
||||||
PRF(printf(" %8d", p->unpackSize));
|
PRF(printf(" %8d", p->unpackSize));
|
||||||
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
|
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
|
||||||
|
|
||||||
case LZMA2_STATE_PACK0:
|
case LZMA2_STATE_PACK0:
|
||||||
p->packSize = (UInt32)b << 8;
|
p->packSize = (UInt32)b << 8;
|
||||||
return LZMA2_STATE_PACK1;
|
return LZMA2_STATE_PACK1;
|
||||||
|
|
||||||
case LZMA2_STATE_PACK1:
|
case LZMA2_STATE_PACK1:
|
||||||
p->packSize |= (UInt32)b;
|
p->packSize |= (UInt32)b;
|
||||||
p->packSize++;
|
p->packSize++;
|
||||||
PRF(printf(" %8d", p->packSize));
|
PRF(printf(" %8d", p->packSize));
|
||||||
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
|
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
|
||||||
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
|
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
|
||||||
|
|
||||||
case LZMA2_STATE_PROP:
|
case LZMA2_STATE_PROP:
|
||||||
{
|
{
|
||||||
int lc, lp;
|
int lc, lp;
|
||||||
if (b >= (9 * 5 * 5))
|
if (b >= (9 * 5 * 5))
|
||||||
return LZMA2_STATE_ERROR;
|
return LZMA2_STATE_ERROR;
|
||||||
lc = b % 9;
|
lc = b % 9;
|
||||||
b /= 9;
|
b /= 9;
|
||||||
p->decoder.prop.pb = b / 5;
|
p->decoder.prop.pb = b / 5;
|
||||||
lp = b % 5;
|
lp = b % 5;
|
||||||
if (lc + lp > LZMA2_LCLP_MAX)
|
if (lc + lp > LZMA2_LCLP_MAX)
|
||||||
return LZMA2_STATE_ERROR;
|
return LZMA2_STATE_ERROR;
|
||||||
p->decoder.prop.lc = lc;
|
p->decoder.prop.lc = lc;
|
||||||
p->decoder.prop.lp = lp;
|
p->decoder.prop.lp = lp;
|
||||||
p->needInitProp = False;
|
p->needInitProp = False;
|
||||||
return LZMA2_STATE_DATA;
|
return LZMA2_STATE_DATA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return LZMA2_STATE_ERROR;
|
return LZMA2_STATE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
|
static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
|
||||||
{
|
{
|
||||||
memcpy(p->dic + p->dicPos, src, size);
|
memcpy(p->dic + p->dicPos, src, size);
|
||||||
p->dicPos += size;
|
p->dicPos += size;
|
||||||
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
|
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
|
||||||
p->checkDicSize = p->prop.dicSize;
|
p->checkDicSize = p->prop.dicSize;
|
||||||
p->processedPos += (UInt32)size;
|
p->processedPos += (UInt32)size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
||||||
{
|
{
|
||||||
p->needFlush = 1;
|
p->needFlush = 1;
|
||||||
p->remainLen = 0;
|
p->remainLen = 0;
|
||||||
p->tempBufSize = 0;
|
p->tempBufSize = 0;
|
||||||
|
|
||||||
if (initDic)
|
if (initDic)
|
||||||
{
|
{
|
||||||
p->processedPos = 0;
|
p->processedPos = 0;
|
||||||
p->checkDicSize = 0;
|
p->checkDicSize = 0;
|
||||||
p->needInitState = 1;
|
p->needInitState = 1;
|
||||||
}
|
}
|
||||||
if (initState)
|
if (initState)
|
||||||
p->needInitState = 1;
|
p->needInitState = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
||||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||||
{
|
{
|
||||||
SizeT inSize = *srcLen;
|
SizeT inSize = *srcLen;
|
||||||
*srcLen = 0;
|
*srcLen = 0;
|
||||||
*status = LZMA_STATUS_NOT_SPECIFIED;
|
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||||
|
|
||||||
while (p->state != LZMA2_STATE_FINISHED)
|
while (p->state != LZMA2_STATE_FINISHED)
|
||||||
{
|
{
|
||||||
SizeT dicPos = p->decoder.dicPos;
|
SizeT dicPos = p->decoder.dicPos;
|
||||||
if (p->state == LZMA2_STATE_ERROR)
|
if (p->state == LZMA2_STATE_ERROR)
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
|
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
|
||||||
{
|
{
|
||||||
*status = LZMA_STATUS_NOT_FINISHED;
|
*status = LZMA_STATUS_NOT_FINISHED;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
|
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
|
||||||
{
|
{
|
||||||
if (*srcLen == inSize)
|
if (*srcLen == inSize)
|
||||||
{
|
{
|
||||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
(*srcLen)++;
|
(*srcLen)++;
|
||||||
p->state = Lzma2Dec_UpdateState(p, *src++);
|
p->state = Lzma2Dec_UpdateState(p, *src++);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
SizeT destSizeCur = dicLimit - dicPos;
|
SizeT destSizeCur = dicLimit - dicPos;
|
||||||
SizeT srcSizeCur = inSize - *srcLen;
|
SizeT srcSizeCur = inSize - *srcLen;
|
||||||
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
|
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
|
||||||
|
|
||||||
if (p->unpackSize <= destSizeCur)
|
if (p->unpackSize <= destSizeCur)
|
||||||
{
|
{
|
||||||
destSizeCur = (SizeT)p->unpackSize;
|
destSizeCur = (SizeT)p->unpackSize;
|
||||||
curFinishMode = LZMA_FINISH_END;
|
curFinishMode = LZMA_FINISH_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
|
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
|
||||||
{
|
{
|
||||||
if (*srcLen == inSize)
|
if (*srcLen == inSize)
|
||||||
{
|
{
|
||||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->state == LZMA2_STATE_DATA)
|
if (p->state == LZMA2_STATE_DATA)
|
||||||
{
|
{
|
||||||
Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
|
Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
|
||||||
if (initDic)
|
if (initDic)
|
||||||
p->needInitProp = p->needInitState = True;
|
p->needInitProp = p->needInitState = True;
|
||||||
else if (p->needInitDic)
|
else if (p->needInitDic)
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
p->needInitDic = False;
|
p->needInitDic = False;
|
||||||
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
|
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srcSizeCur > destSizeCur)
|
if (srcSizeCur > destSizeCur)
|
||||||
srcSizeCur = destSizeCur;
|
srcSizeCur = destSizeCur;
|
||||||
|
|
||||||
if (srcSizeCur == 0)
|
if (srcSizeCur == 0)
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
|
|
||||||
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
|
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
|
||||||
|
|
||||||
src += srcSizeCur;
|
src += srcSizeCur;
|
||||||
*srcLen += srcSizeCur;
|
*srcLen += srcSizeCur;
|
||||||
p->unpackSize -= (UInt32)srcSizeCur;
|
p->unpackSize -= (UInt32)srcSizeCur;
|
||||||
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
|
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SizeT outSizeProcessed;
|
SizeT outSizeProcessed;
|
||||||
SRes res;
|
SRes res;
|
||||||
|
|
||||||
if (p->state == LZMA2_STATE_DATA)
|
if (p->state == LZMA2_STATE_DATA)
|
||||||
{
|
{
|
||||||
int mode = LZMA2_GET_LZMA_MODE(p);
|
int mode = LZMA2_GET_LZMA_MODE(p);
|
||||||
Bool initDic = (mode == 3);
|
Bool initDic = (mode == 3);
|
||||||
Bool initState = (mode > 0);
|
Bool initState = (mode > 0);
|
||||||
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
|
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
|
|
||||||
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
|
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
|
||||||
p->needInitDic = False;
|
p->needInitDic = False;
|
||||||
p->needInitState = False;
|
p->needInitState = False;
|
||||||
p->state = LZMA2_STATE_DATA_CONT;
|
p->state = LZMA2_STATE_DATA_CONT;
|
||||||
}
|
}
|
||||||
if (srcSizeCur > p->packSize)
|
if (srcSizeCur > p->packSize)
|
||||||
srcSizeCur = (SizeT)p->packSize;
|
srcSizeCur = (SizeT)p->packSize;
|
||||||
|
|
||||||
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
|
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
|
||||||
|
|
||||||
src += srcSizeCur;
|
src += srcSizeCur;
|
||||||
*srcLen += srcSizeCur;
|
*srcLen += srcSizeCur;
|
||||||
p->packSize -= (UInt32)srcSizeCur;
|
p->packSize -= (UInt32)srcSizeCur;
|
||||||
|
|
||||||
outSizeProcessed = p->decoder.dicPos - dicPos;
|
outSizeProcessed = p->decoder.dicPos - dicPos;
|
||||||
p->unpackSize -= (UInt32)outSizeProcessed;
|
p->unpackSize -= (UInt32)outSizeProcessed;
|
||||||
|
|
||||||
RINOK(res);
|
RINOK(res);
|
||||||
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
if (srcSizeCur == 0 && outSizeProcessed == 0)
|
if (srcSizeCur == 0 && outSizeProcessed == 0)
|
||||||
{
|
{
|
||||||
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
|
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
|
||||||
p->unpackSize != 0 || p->packSize != 0)
|
p->unpackSize != 0 || p->packSize != 0)
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
p->state = LZMA2_STATE_CONTROL;
|
p->state = LZMA2_STATE_CONTROL;
|
||||||
}
|
}
|
||||||
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
|
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
|
||||||
*status = LZMA_STATUS_NOT_FINISHED;
|
*status = LZMA_STATUS_NOT_FINISHED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||||
{
|
{
|
||||||
SizeT outSize = *destLen, inSize = *srcLen;
|
SizeT outSize = *destLen, inSize = *srcLen;
|
||||||
*srcLen = *destLen = 0;
|
*srcLen = *destLen = 0;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
SizeT srcSizeCur = inSize, outSizeCur, dicPos;
|
SizeT srcSizeCur = inSize, outSizeCur, dicPos;
|
||||||
ELzmaFinishMode curFinishMode;
|
ELzmaFinishMode curFinishMode;
|
||||||
SRes res;
|
SRes res;
|
||||||
if (p->decoder.dicPos == p->decoder.dicBufSize)
|
if (p->decoder.dicPos == p->decoder.dicBufSize)
|
||||||
p->decoder.dicPos = 0;
|
p->decoder.dicPos = 0;
|
||||||
dicPos = p->decoder.dicPos;
|
dicPos = p->decoder.dicPos;
|
||||||
if (outSize > p->decoder.dicBufSize - dicPos)
|
if (outSize > p->decoder.dicBufSize - dicPos)
|
||||||
{
|
{
|
||||||
outSizeCur = p->decoder.dicBufSize;
|
outSizeCur = p->decoder.dicBufSize;
|
||||||
curFinishMode = LZMA_FINISH_ANY;
|
curFinishMode = LZMA_FINISH_ANY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
outSizeCur = dicPos + outSize;
|
outSizeCur = dicPos + outSize;
|
||||||
curFinishMode = finishMode;
|
curFinishMode = finishMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
|
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
|
||||||
src += srcSizeCur;
|
src += srcSizeCur;
|
||||||
inSize -= srcSizeCur;
|
inSize -= srcSizeCur;
|
||||||
*srcLen += srcSizeCur;
|
*srcLen += srcSizeCur;
|
||||||
outSizeCur = p->decoder.dicPos - dicPos;
|
outSizeCur = p->decoder.dicPos - dicPos;
|
||||||
memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
|
memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
|
||||||
dest += outSizeCur;
|
dest += outSizeCur;
|
||||||
outSize -= outSizeCur;
|
outSize -= outSizeCur;
|
||||||
*destLen += outSizeCur;
|
*destLen += outSizeCur;
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
return res;
|
return res;
|
||||||
if (outSizeCur == 0 || outSize == 0)
|
if (outSizeCur == 0 || outSize == 0)
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
|
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
CLzma2Dec decoder;
|
CLzma2Dec decoder;
|
||||||
SRes res;
|
SRes res;
|
||||||
SizeT outSize = *destLen, inSize = *srcLen;
|
SizeT outSize = *destLen, inSize = *srcLen;
|
||||||
Byte props[LZMA_PROPS_SIZE];
|
Byte props[LZMA_PROPS_SIZE];
|
||||||
|
|
||||||
Lzma2Dec_Construct(&decoder);
|
Lzma2Dec_Construct(&decoder);
|
||||||
|
|
||||||
*destLen = *srcLen = 0;
|
*destLen = *srcLen = 0;
|
||||||
*status = LZMA_STATUS_NOT_SPECIFIED;
|
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||||
decoder.decoder.dic = dest;
|
decoder.decoder.dic = dest;
|
||||||
decoder.decoder.dicBufSize = outSize;
|
decoder.decoder.dicBufSize = outSize;
|
||||||
|
|
||||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||||
RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc));
|
RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc));
|
||||||
|
|
||||||
*srcLen = inSize;
|
*srcLen = inSize;
|
||||||
res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status);
|
res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status);
|
||||||
*destLen = decoder.decoder.dicPos;
|
*destLen = decoder.decoder.dicPos;
|
||||||
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||||
res = SZ_ERROR_INPUT_EOF;
|
res = SZ_ERROR_INPUT_EOF;
|
||||||
|
|
||||||
LzmaDec_FreeProbs(&decoder.decoder, alloc);
|
LzmaDec_FreeProbs(&decoder.decoder, alloc);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,84 +1,84 @@
|
||||||
/* Lzma2Dec.h -- LZMA2 Decoder
|
/* Lzma2Dec.h -- LZMA2 Decoder
|
||||||
2009-05-03 : Igor Pavlov : Public domain */
|
2009-05-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZMA2_DEC_H
|
#ifndef __LZMA2_DEC_H
|
||||||
#define __LZMA2_DEC_H
|
#define __LZMA2_DEC_H
|
||||||
|
|
||||||
#include "LzmaDec.h"
|
#include "LzmaDec.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ---------- State Interface ---------- */
|
/* ---------- State Interface ---------- */
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CLzmaDec decoder;
|
CLzmaDec decoder;
|
||||||
UInt32 packSize;
|
UInt32 packSize;
|
||||||
UInt32 unpackSize;
|
UInt32 unpackSize;
|
||||||
int state;
|
int state;
|
||||||
Byte control;
|
Byte control;
|
||||||
Bool needInitDic;
|
Bool needInitDic;
|
||||||
Bool needInitState;
|
Bool needInitState;
|
||||||
Bool needInitProp;
|
Bool needInitProp;
|
||||||
} CLzma2Dec;
|
} CLzma2Dec;
|
||||||
|
|
||||||
#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
|
#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
|
||||||
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
|
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
|
||||||
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
|
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
|
||||||
|
|
||||||
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
|
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
|
||||||
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
|
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
|
||||||
void Lzma2Dec_Init(CLzma2Dec *p);
|
void Lzma2Dec_Init(CLzma2Dec *p);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
finishMode:
|
finishMode:
|
||||||
It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
|
It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
|
||||||
LZMA_FINISH_ANY - use smallest number of input bytes
|
LZMA_FINISH_ANY - use smallest number of input bytes
|
||||||
LZMA_FINISH_END - read EndOfStream marker after decoding
|
LZMA_FINISH_END - read EndOfStream marker after decoding
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
SZ_OK
|
SZ_OK
|
||||||
status:
|
status:
|
||||||
LZMA_STATUS_FINISHED_WITH_MARK
|
LZMA_STATUS_FINISHED_WITH_MARK
|
||||||
LZMA_STATUS_NOT_FINISHED
|
LZMA_STATUS_NOT_FINISHED
|
||||||
LZMA_STATUS_NEEDS_MORE_INPUT
|
LZMA_STATUS_NEEDS_MORE_INPUT
|
||||||
SZ_ERROR_DATA - Data error
|
SZ_ERROR_DATA - Data error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
||||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||||
|
|
||||||
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,
|
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,
|
||||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||||
|
|
||||||
|
|
||||||
/* ---------- One Call Interface ---------- */
|
/* ---------- One Call Interface ---------- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
finishMode:
|
finishMode:
|
||||||
It has meaning only if the decoding reaches output limit (*destLen).
|
It has meaning only if the decoding reaches output limit (*destLen).
|
||||||
LZMA_FINISH_ANY - use smallest number of input bytes
|
LZMA_FINISH_ANY - use smallest number of input bytes
|
||||||
LZMA_FINISH_END - read EndOfStream marker after decoding
|
LZMA_FINISH_END - read EndOfStream marker after decoding
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
SZ_OK
|
SZ_OK
|
||||||
status:
|
status:
|
||||||
LZMA_STATUS_FINISHED_WITH_MARK
|
LZMA_STATUS_FINISHED_WITH_MARK
|
||||||
LZMA_STATUS_NOT_FINISHED
|
LZMA_STATUS_NOT_FINISHED
|
||||||
SZ_ERROR_DATA - Data error
|
SZ_ERROR_DATA - Data error
|
||||||
SZ_ERROR_MEM - Memory allocation error
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
|
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
2000
fex/7z_C/LzmaDec.c
2000
fex/7z_C/LzmaDec.c
File diff suppressed because it is too large
Load Diff
|
@ -1,231 +1,231 @@
|
||||||
/* LzmaDec.h -- LZMA Decoder
|
/* LzmaDec.h -- LZMA Decoder
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
2009-02-07 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZMA_DEC_H
|
#ifndef __LZMA_DEC_H
|
||||||
#define __LZMA_DEC_H
|
#define __LZMA_DEC_H
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* #define _LZMA_PROB32 */
|
/* #define _LZMA_PROB32 */
|
||||||
/* _LZMA_PROB32 can increase the speed on some CPUs,
|
/* _LZMA_PROB32 can increase the speed on some CPUs,
|
||||||
but memory usage for CLzmaDec::probs will be doubled in that case */
|
but memory usage for CLzmaDec::probs will be doubled in that case */
|
||||||
|
|
||||||
#ifdef _LZMA_PROB32
|
#ifdef _LZMA_PROB32
|
||||||
#define CLzmaProb UInt32
|
#define CLzmaProb UInt32
|
||||||
#else
|
#else
|
||||||
#define CLzmaProb UInt16
|
#define CLzmaProb UInt16
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* ---------- LZMA Properties ---------- */
|
/* ---------- LZMA Properties ---------- */
|
||||||
|
|
||||||
#define LZMA_PROPS_SIZE 5
|
#define LZMA_PROPS_SIZE 5
|
||||||
|
|
||||||
typedef struct _CLzmaProps
|
typedef struct _CLzmaProps
|
||||||
{
|
{
|
||||||
unsigned lc, lp, pb;
|
unsigned lc, lp, pb;
|
||||||
UInt32 dicSize;
|
UInt32 dicSize;
|
||||||
} CLzmaProps;
|
} CLzmaProps;
|
||||||
|
|
||||||
/* LzmaProps_Decode - decodes properties
|
/* LzmaProps_Decode - decodes properties
|
||||||
Returns:
|
Returns:
|
||||||
SZ_OK
|
SZ_OK
|
||||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
|
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
|
||||||
|
|
||||||
|
|
||||||
/* ---------- LZMA Decoder state ---------- */
|
/* ---------- LZMA Decoder state ---------- */
|
||||||
|
|
||||||
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
|
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
|
||||||
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
|
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
|
||||||
|
|
||||||
#define LZMA_REQUIRED_INPUT_MAX 20
|
#define LZMA_REQUIRED_INPUT_MAX 20
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CLzmaProps prop;
|
CLzmaProps prop;
|
||||||
CLzmaProb *probs;
|
CLzmaProb *probs;
|
||||||
Byte *dic;
|
Byte *dic;
|
||||||
const Byte *buf;
|
const Byte *buf;
|
||||||
UInt32 range, code;
|
UInt32 range, code;
|
||||||
SizeT dicPos;
|
SizeT dicPos;
|
||||||
SizeT dicBufSize;
|
SizeT dicBufSize;
|
||||||
UInt32 processedPos;
|
UInt32 processedPos;
|
||||||
UInt32 checkDicSize;
|
UInt32 checkDicSize;
|
||||||
unsigned state;
|
unsigned state;
|
||||||
UInt32 reps[4];
|
UInt32 reps[4];
|
||||||
unsigned remainLen;
|
unsigned remainLen;
|
||||||
int needFlush;
|
int needFlush;
|
||||||
int needInitState;
|
int needInitState;
|
||||||
UInt32 numProbs;
|
UInt32 numProbs;
|
||||||
unsigned tempBufSize;
|
unsigned tempBufSize;
|
||||||
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
|
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
|
||||||
} CLzmaDec;
|
} CLzmaDec;
|
||||||
|
|
||||||
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
|
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
|
||||||
|
|
||||||
void LzmaDec_Init(CLzmaDec *p);
|
void LzmaDec_Init(CLzmaDec *p);
|
||||||
|
|
||||||
/* There are two types of LZMA streams:
|
/* There are two types of LZMA streams:
|
||||||
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
||||||
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
|
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
LZMA_FINISH_ANY, /* finish at any point */
|
LZMA_FINISH_ANY, /* finish at any point */
|
||||||
LZMA_FINISH_END /* block must be finished at the end */
|
LZMA_FINISH_END /* block must be finished at the end */
|
||||||
} ELzmaFinishMode;
|
} ELzmaFinishMode;
|
||||||
|
|
||||||
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
|
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
|
||||||
|
|
||||||
You must use LZMA_FINISH_END, when you know that current output buffer
|
You must use LZMA_FINISH_END, when you know that current output buffer
|
||||||
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
|
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
|
||||||
|
|
||||||
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
|
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
|
||||||
and output value of destLen will be less than output buffer size limit.
|
and output value of destLen will be less than output buffer size limit.
|
||||||
You can check status result also.
|
You can check status result also.
|
||||||
|
|
||||||
You can use multiple checks to test data integrity after full decompression:
|
You can use multiple checks to test data integrity after full decompression:
|
||||||
1) Check Result and "status" variable.
|
1) Check Result and "status" variable.
|
||||||
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
|
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
|
||||||
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
|
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
|
||||||
You must use correct finish mode in that case. */
|
You must use correct finish mode in that case. */
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
||||||
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
||||||
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
|
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
|
||||||
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
|
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
|
||||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
|
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
|
||||||
} ELzmaStatus;
|
} ELzmaStatus;
|
||||||
|
|
||||||
/* ELzmaStatus is used only as output value for function call */
|
/* ELzmaStatus is used only as output value for function call */
|
||||||
|
|
||||||
|
|
||||||
/* ---------- Interfaces ---------- */
|
/* ---------- Interfaces ---------- */
|
||||||
|
|
||||||
/* There are 3 levels of interfaces:
|
/* There are 3 levels of interfaces:
|
||||||
1) Dictionary Interface
|
1) Dictionary Interface
|
||||||
2) Buffer Interface
|
2) Buffer Interface
|
||||||
3) One Call Interface
|
3) One Call Interface
|
||||||
You can select any of these interfaces, but don't mix functions from different
|
You can select any of these interfaces, but don't mix functions from different
|
||||||
groups for same object. */
|
groups for same object. */
|
||||||
|
|
||||||
|
|
||||||
/* There are two variants to allocate state for Dictionary Interface:
|
/* There are two variants to allocate state for Dictionary Interface:
|
||||||
1) LzmaDec_Allocate / LzmaDec_Free
|
1) LzmaDec_Allocate / LzmaDec_Free
|
||||||
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
|
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
|
||||||
You can use variant 2, if you set dictionary buffer manually.
|
You can use variant 2, if you set dictionary buffer manually.
|
||||||
For Buffer Interface you must always use variant 1.
|
For Buffer Interface you must always use variant 1.
|
||||||
|
|
||||||
LzmaDec_Allocate* can return:
|
LzmaDec_Allocate* can return:
|
||||||
SZ_OK
|
SZ_OK
|
||||||
SZ_ERROR_MEM - Memory allocation error
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
|
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
|
||||||
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
|
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
|
||||||
|
|
||||||
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
|
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
|
||||||
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
||||||
|
|
||||||
/* ---------- Dictionary Interface ---------- */
|
/* ---------- Dictionary Interface ---------- */
|
||||||
|
|
||||||
/* You can use it, if you want to eliminate the overhead for data copying from
|
/* You can use it, if you want to eliminate the overhead for data copying from
|
||||||
dictionary to some other external buffer.
|
dictionary to some other external buffer.
|
||||||
You must work with CLzmaDec variables directly in this interface.
|
You must work with CLzmaDec variables directly in this interface.
|
||||||
|
|
||||||
STEPS:
|
STEPS:
|
||||||
LzmaDec_Constr()
|
LzmaDec_Constr()
|
||||||
LzmaDec_Allocate()
|
LzmaDec_Allocate()
|
||||||
for (each new stream)
|
for (each new stream)
|
||||||
{
|
{
|
||||||
LzmaDec_Init()
|
LzmaDec_Init()
|
||||||
while (it needs more decompression)
|
while (it needs more decompression)
|
||||||
{
|
{
|
||||||
LzmaDec_DecodeToDic()
|
LzmaDec_DecodeToDic()
|
||||||
use data from CLzmaDec::dic and update CLzmaDec::dicPos
|
use data from CLzmaDec::dic and update CLzmaDec::dicPos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LzmaDec_Free()
|
LzmaDec_Free()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* LzmaDec_DecodeToDic
|
/* LzmaDec_DecodeToDic
|
||||||
|
|
||||||
The decoding to internal dictionary buffer (CLzmaDec::dic).
|
The decoding to internal dictionary buffer (CLzmaDec::dic).
|
||||||
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
|
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
|
||||||
|
|
||||||
finishMode:
|
finishMode:
|
||||||
It has meaning only if the decoding reaches output limit (dicLimit).
|
It has meaning only if the decoding reaches output limit (dicLimit).
|
||||||
LZMA_FINISH_ANY - Decode just dicLimit bytes.
|
LZMA_FINISH_ANY - Decode just dicLimit bytes.
|
||||||
LZMA_FINISH_END - Stream must be finished after dicLimit.
|
LZMA_FINISH_END - Stream must be finished after dicLimit.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
SZ_OK
|
SZ_OK
|
||||||
status:
|
status:
|
||||||
LZMA_STATUS_FINISHED_WITH_MARK
|
LZMA_STATUS_FINISHED_WITH_MARK
|
||||||
LZMA_STATUS_NOT_FINISHED
|
LZMA_STATUS_NOT_FINISHED
|
||||||
LZMA_STATUS_NEEDS_MORE_INPUT
|
LZMA_STATUS_NEEDS_MORE_INPUT
|
||||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||||
SZ_ERROR_DATA - Data error
|
SZ_ERROR_DATA - Data error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
|
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
|
||||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||||
|
|
||||||
|
|
||||||
/* ---------- Buffer Interface ---------- */
|
/* ---------- Buffer Interface ---------- */
|
||||||
|
|
||||||
/* It's zlib-like interface.
|
/* It's zlib-like interface.
|
||||||
See LzmaDec_DecodeToDic description for information about STEPS and return results,
|
See LzmaDec_DecodeToDic description for information about STEPS and return results,
|
||||||
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
|
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
|
||||||
to work with CLzmaDec variables manually.
|
to work with CLzmaDec variables manually.
|
||||||
|
|
||||||
finishMode:
|
finishMode:
|
||||||
It has meaning only if the decoding reaches output limit (*destLen).
|
It has meaning only if the decoding reaches output limit (*destLen).
|
||||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
||||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||||
|
|
||||||
|
|
||||||
/* ---------- One Call Interface ---------- */
|
/* ---------- One Call Interface ---------- */
|
||||||
|
|
||||||
/* LzmaDecode
|
/* LzmaDecode
|
||||||
|
|
||||||
finishMode:
|
finishMode:
|
||||||
It has meaning only if the decoding reaches output limit (*destLen).
|
It has meaning only if the decoding reaches output limit (*destLen).
|
||||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
SZ_OK
|
SZ_OK
|
||||||
status:
|
status:
|
||||||
LZMA_STATUS_FINISHED_WITH_MARK
|
LZMA_STATUS_FINISHED_WITH_MARK
|
||||||
LZMA_STATUS_NOT_FINISHED
|
LZMA_STATUS_NOT_FINISHED
|
||||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||||
SZ_ERROR_DATA - Data error
|
SZ_ERROR_DATA - Data error
|
||||||
SZ_ERROR_MEM - Memory allocation error
|
SZ_ERROR_MEM - Memory allocation error
|
||||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||||
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||||
ELzmaStatus *status, ISzAlloc *alloc);
|
ELzmaStatus *status, ISzAlloc *alloc);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
508
fex/7z_C/Types.h
508
fex/7z_C/Types.h
|
@ -1,254 +1,254 @@
|
||||||
/* Types.h -- Basic types
|
/* Types.h -- Basic types
|
||||||
2010-10-09 : Igor Pavlov : Public domain */
|
2010-10-09 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_TYPES_H
|
#ifndef __7Z_TYPES_H
|
||||||
#define __7Z_TYPES_H
|
#define __7Z_TYPES_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef EXTERN_C_BEGIN
|
#ifndef EXTERN_C_BEGIN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#define EXTERN_C_BEGIN extern "C" {
|
#define EXTERN_C_BEGIN extern "C" {
|
||||||
#define EXTERN_C_END }
|
#define EXTERN_C_END }
|
||||||
#else
|
#else
|
||||||
#define EXTERN_C_BEGIN
|
#define EXTERN_C_BEGIN
|
||||||
#define EXTERN_C_END
|
#define EXTERN_C_END
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXTERN_C_BEGIN
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
#define SZ_OK 0
|
#define SZ_OK 0
|
||||||
|
|
||||||
#define SZ_ERROR_DATA 1
|
#define SZ_ERROR_DATA 1
|
||||||
#define SZ_ERROR_MEM 2
|
#define SZ_ERROR_MEM 2
|
||||||
#define SZ_ERROR_CRC 3
|
#define SZ_ERROR_CRC 3
|
||||||
#define SZ_ERROR_UNSUPPORTED 4
|
#define SZ_ERROR_UNSUPPORTED 4
|
||||||
#define SZ_ERROR_PARAM 5
|
#define SZ_ERROR_PARAM 5
|
||||||
#define SZ_ERROR_INPUT_EOF 6
|
#define SZ_ERROR_INPUT_EOF 6
|
||||||
#define SZ_ERROR_OUTPUT_EOF 7
|
#define SZ_ERROR_OUTPUT_EOF 7
|
||||||
#define SZ_ERROR_READ 8
|
#define SZ_ERROR_READ 8
|
||||||
#define SZ_ERROR_WRITE 9
|
#define SZ_ERROR_WRITE 9
|
||||||
#define SZ_ERROR_PROGRESS 10
|
#define SZ_ERROR_PROGRESS 10
|
||||||
#define SZ_ERROR_FAIL 11
|
#define SZ_ERROR_FAIL 11
|
||||||
#define SZ_ERROR_THREAD 12
|
#define SZ_ERROR_THREAD 12
|
||||||
|
|
||||||
#define SZ_ERROR_ARCHIVE 16
|
#define SZ_ERROR_ARCHIVE 16
|
||||||
#define SZ_ERROR_NO_ARCHIVE 17
|
#define SZ_ERROR_NO_ARCHIVE 17
|
||||||
|
|
||||||
typedef int SRes;
|
typedef int SRes;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
typedef DWORD WRes;
|
typedef DWORD WRes;
|
||||||
#else
|
#else
|
||||||
typedef int WRes;
|
typedef int WRes;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef RINOK
|
#ifndef RINOK
|
||||||
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef unsigned char Byte;
|
typedef unsigned char Byte;
|
||||||
typedef short Int16;
|
typedef short Int16;
|
||||||
typedef unsigned short UInt16;
|
typedef unsigned short UInt16;
|
||||||
|
|
||||||
#ifdef _LZMA_UINT32_IS_ULONG
|
#ifdef _LZMA_UINT32_IS_ULONG
|
||||||
typedef long Int32;
|
typedef long Int32;
|
||||||
typedef unsigned long UInt32;
|
typedef unsigned long UInt32;
|
||||||
#else
|
#else
|
||||||
typedef int Int32;
|
typedef int Int32;
|
||||||
typedef unsigned int UInt32;
|
typedef unsigned int UInt32;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _SZ_NO_INT_64
|
#ifdef _SZ_NO_INT_64
|
||||||
|
|
||||||
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
|
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
|
||||||
NOTES: Some code will work incorrectly in that case! */
|
NOTES: Some code will work incorrectly in that case! */
|
||||||
|
|
||||||
typedef long Int64;
|
typedef long Int64;
|
||||||
typedef unsigned long UInt64;
|
typedef unsigned long UInt64;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||||
typedef __int64 Int64;
|
typedef __int64 Int64;
|
||||||
typedef unsigned __int64 UInt64;
|
typedef unsigned __int64 UInt64;
|
||||||
#define UINT64_CONST(n) n
|
#define UINT64_CONST(n) n
|
||||||
#else
|
#else
|
||||||
typedef long long int Int64;
|
typedef long long int Int64;
|
||||||
typedef unsigned long long int UInt64;
|
typedef unsigned long long int UInt64;
|
||||||
#define UINT64_CONST(n) n ## ULL
|
#define UINT64_CONST(n) n ## ULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _LZMA_NO_SYSTEM_SIZE_T
|
#ifdef _LZMA_NO_SYSTEM_SIZE_T
|
||||||
typedef UInt32 SizeT;
|
typedef UInt32 SizeT;
|
||||||
#else
|
#else
|
||||||
typedef size_t SizeT;
|
typedef size_t SizeT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef int Bool;
|
typedef int Bool;
|
||||||
#define True 1
|
#define True 1
|
||||||
#define False 0
|
#define False 0
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define MY_STD_CALL __stdcall
|
#define MY_STD_CALL __stdcall
|
||||||
#else
|
#else
|
||||||
#define MY_STD_CALL
|
#define MY_STD_CALL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
#if _MSC_VER >= 1300
|
#if _MSC_VER >= 1300
|
||||||
#define MY_NO_INLINE __declspec(noinline)
|
#define MY_NO_INLINE __declspec(noinline)
|
||||||
#else
|
#else
|
||||||
#define MY_NO_INLINE
|
#define MY_NO_INLINE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MY_CDECL __cdecl
|
#define MY_CDECL __cdecl
|
||||||
#define MY_FAST_CALL __fastcall
|
#define MY_FAST_CALL __fastcall
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define MY_CDECL
|
#define MY_CDECL
|
||||||
#define MY_FAST_CALL
|
#define MY_FAST_CALL
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* The following interfaces use first parameter as pointer to structure */
|
/* The following interfaces use first parameter as pointer to structure */
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
|
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
|
||||||
} IByteIn;
|
} IByteIn;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
void (*Write)(void *p, Byte b);
|
void (*Write)(void *p, Byte b);
|
||||||
} IByteOut;
|
} IByteOut;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||||
(output(*size) < input(*size)) is allowed */
|
(output(*size) < input(*size)) is allowed */
|
||||||
} ISeqInStream;
|
} ISeqInStream;
|
||||||
|
|
||||||
/* it can return SZ_ERROR_INPUT_EOF */
|
/* it can return SZ_ERROR_INPUT_EOF */
|
||||||
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
|
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
|
||||||
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
|
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
|
||||||
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
|
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
size_t (*Write)(void *p, const void *buf, size_t size);
|
size_t (*Write)(void *p, const void *buf, size_t size);
|
||||||
/* Returns: result - the number of actually written bytes.
|
/* Returns: result - the number of actually written bytes.
|
||||||
(result < size) means error */
|
(result < size) means error */
|
||||||
} ISeqOutStream;
|
} ISeqOutStream;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
SZ_SEEK_SET = 0,
|
SZ_SEEK_SET = 0,
|
||||||
SZ_SEEK_CUR = 1,
|
SZ_SEEK_CUR = 1,
|
||||||
SZ_SEEK_END = 2
|
SZ_SEEK_END = 2
|
||||||
} ESzSeek;
|
} ESzSeek;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
||||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||||
} ISeekInStream;
|
} ISeekInStream;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
SRes (*Look)(void *p, const void **buf, size_t *size);
|
SRes (*Look)(void *p, const void **buf, size_t *size);
|
||||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||||
(output(*size) > input(*size)) is not allowed
|
(output(*size) > input(*size)) is not allowed
|
||||||
(output(*size) < input(*size)) is allowed */
|
(output(*size) < input(*size)) is allowed */
|
||||||
SRes (*Skip)(void *p, size_t offset);
|
SRes (*Skip)(void *p, size_t offset);
|
||||||
/* offset must be <= output(*size) of Look */
|
/* offset must be <= output(*size) of Look */
|
||||||
|
|
||||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||||
/* reads directly (without buffer). It's same as ISeqInStream::Read */
|
/* reads directly (without buffer). It's same as ISeqInStream::Read */
|
||||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||||
} ILookInStream;
|
} ILookInStream;
|
||||||
|
|
||||||
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
|
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
|
||||||
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
|
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
|
||||||
|
|
||||||
/* reads via ILookInStream::Read */
|
/* reads via ILookInStream::Read */
|
||||||
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
|
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
|
||||||
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
|
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
|
||||||
|
|
||||||
#define LookToRead_BUF_SIZE (1 << 14)
|
#define LookToRead_BUF_SIZE (1 << 14)
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ILookInStream s;
|
ILookInStream s;
|
||||||
ISeekInStream *realStream;
|
ISeekInStream *realStream;
|
||||||
size_t pos;
|
size_t pos;
|
||||||
size_t size;
|
size_t size;
|
||||||
Byte buf[LookToRead_BUF_SIZE];
|
Byte buf[LookToRead_BUF_SIZE];
|
||||||
} CLookToRead;
|
} CLookToRead;
|
||||||
|
|
||||||
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
|
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
|
||||||
void LookToRead_Init(CLookToRead *p);
|
void LookToRead_Init(CLookToRead *p);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ISeqInStream s;
|
ISeqInStream s;
|
||||||
ILookInStream *realStream;
|
ILookInStream *realStream;
|
||||||
} CSecToLook;
|
} CSecToLook;
|
||||||
|
|
||||||
void SecToLook_CreateVTable(CSecToLook *p);
|
void SecToLook_CreateVTable(CSecToLook *p);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ISeqInStream s;
|
ISeqInStream s;
|
||||||
ILookInStream *realStream;
|
ILookInStream *realStream;
|
||||||
} CSecToRead;
|
} CSecToRead;
|
||||||
|
|
||||||
void SecToRead_CreateVTable(CSecToRead *p);
|
void SecToRead_CreateVTable(CSecToRead *p);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
|
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
|
||||||
/* Returns: result. (result != SZ_OK) means break.
|
/* Returns: result. (result != SZ_OK) means break.
|
||||||
Value (UInt64)(Int64)-1 for size means unknown value. */
|
Value (UInt64)(Int64)-1 for size means unknown value. */
|
||||||
} ICompressProgress;
|
} ICompressProgress;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
void *(*Alloc)(void *p, size_t size);
|
void *(*Alloc)(void *p, size_t size);
|
||||||
void (*Free)(void *p, void *address); /* address can be 0 */
|
void (*Free)(void *p, void *address); /* address can be 0 */
|
||||||
} ISzAlloc;
|
} ISzAlloc;
|
||||||
|
|
||||||
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
||||||
#define IAlloc_Free(p, a) (p)->Free((p), a)
|
#define IAlloc_Free(p, a) (p)->Free((p), a)
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#define CHAR_PATH_SEPARATOR '\\'
|
#define CHAR_PATH_SEPARATOR '\\'
|
||||||
#define WCHAR_PATH_SEPARATOR L'\\'
|
#define WCHAR_PATH_SEPARATOR L'\\'
|
||||||
#define STRING_PATH_SEPARATOR "\\"
|
#define STRING_PATH_SEPARATOR "\\"
|
||||||
#define WSTRING_PATH_SEPARATOR L"\\"
|
#define WSTRING_PATH_SEPARATOR L"\\"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define CHAR_PATH_SEPARATOR '/'
|
#define CHAR_PATH_SEPARATOR '/'
|
||||||
#define WCHAR_PATH_SEPARATOR L'/'
|
#define WCHAR_PATH_SEPARATOR L'/'
|
||||||
#define STRING_PATH_SEPARATOR "/"
|
#define STRING_PATH_SEPARATOR "/"
|
||||||
#define WSTRING_PATH_SEPARATOR L"/"
|
#define WSTRING_PATH_SEPARATOR L"/"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXTERN_C_END
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
// Presents a single file as an "archive" of just that file.
|
// Presents a single file as an "archive" of just that file.
|
||||||
|
|
||||||
// File_Extractor 1.0.0
|
// File_Extractor 1.0.0
|
||||||
#ifndef BINARY_EXTRACTOR_H
|
#ifndef BINARY_EXTRACTOR_H
|
||||||
#define BINARY_EXTRACTOR_H
|
#define BINARY_EXTRACTOR_H
|
||||||
|
|
||||||
#include "File_Extractor.h"
|
#include "File_Extractor.h"
|
||||||
|
|
||||||
class Binary_Extractor : public File_Extractor {
|
class Binary_Extractor : public File_Extractor {
|
||||||
public:
|
public:
|
||||||
Binary_Extractor();
|
Binary_Extractor();
|
||||||
virtual ~Binary_Extractor();
|
virtual ~Binary_Extractor();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual blargg_err_t open_path_v();
|
virtual blargg_err_t open_path_v();
|
||||||
virtual blargg_err_t open_v();
|
virtual blargg_err_t open_v();
|
||||||
virtual void close_v();
|
virtual void close_v();
|
||||||
|
|
||||||
virtual blargg_err_t next_v();
|
virtual blargg_err_t next_v();
|
||||||
virtual blargg_err_t rewind_v();
|
virtual blargg_err_t rewind_v();
|
||||||
|
|
||||||
virtual blargg_err_t stat_v();
|
virtual blargg_err_t stat_v();
|
||||||
virtual blargg_err_t extract_v( void*, int );
|
virtual blargg_err_t extract_v( void*, int );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,264 +1,264 @@
|
||||||
// Lightweight interface for reading data from byte stream
|
// Lightweight interface for reading data from byte stream
|
||||||
|
|
||||||
// File_Extractor 1.0.0
|
// File_Extractor 1.0.0
|
||||||
#ifndef DATA_READER_H
|
#ifndef DATA_READER_H
|
||||||
#define DATA_READER_H
|
#define DATA_READER_H
|
||||||
|
|
||||||
#include "blargg_common.h"
|
#include "blargg_common.h"
|
||||||
|
|
||||||
/* Some functions accept a long instead of int for convenience where caller has
|
/* Some functions accept a long instead of int for convenience where caller has
|
||||||
a long due to some other interface, and would otherwise have to get a warning,
|
a long due to some other interface, and would otherwise have to get a warning,
|
||||||
or cast it (and verify that it wasn't outside the range of an int).
|
or cast it (and verify that it wasn't outside the range of an int).
|
||||||
|
|
||||||
To really support huge (>2GB) files, long isn't a solution, since there's no
|
To really support huge (>2GB) files, long isn't a solution, since there's no
|
||||||
guarantee it's more than 32 bits. We'd need to use long long (if available), or
|
guarantee it's more than 32 bits. We'd need to use long long (if available), or
|
||||||
something compiler-specific, and change all places file sizes or offsets are
|
something compiler-specific, and change all places file sizes or offsets are
|
||||||
used. */
|
used. */
|
||||||
|
|
||||||
// Supports reading and finding out how many bytes are remaining
|
// Supports reading and finding out how many bytes are remaining
|
||||||
class Data_Reader {
|
class Data_Reader {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Reads min(*n,remain()) bytes and sets *n to this number, thus trying to read more
|
// Reads min(*n,remain()) bytes and sets *n to this number, thus trying to read more
|
||||||
// tham remain() bytes doesn't result in error, just *n being set to remain().
|
// tham remain() bytes doesn't result in error, just *n being set to remain().
|
||||||
blargg_err_t read_avail( void* p, int* n );
|
blargg_err_t read_avail( void* p, int* n );
|
||||||
blargg_err_t read_avail( void* p, long* n );
|
blargg_err_t read_avail( void* p, long* n );
|
||||||
|
|
||||||
// Reads exactly n bytes, or returns error if they couldn't ALL be read.
|
// Reads exactly n bytes, or returns error if they couldn't ALL be read.
|
||||||
// Reading past end of file results in blargg_err_file_eof.
|
// Reading past end of file results in blargg_err_file_eof.
|
||||||
blargg_err_t read( void* p, int n );
|
blargg_err_t read( void* p, int n );
|
||||||
|
|
||||||
// Number of bytes remaining until end of file
|
// Number of bytes remaining until end of file
|
||||||
int remain() const { return remain_; }
|
int remain() const { return remain_; }
|
||||||
|
|
||||||
// Reads and discards n bytes. Skipping past end of file results in blargg_err_file_eof.
|
// Reads and discards n bytes. Skipping past end of file results in blargg_err_file_eof.
|
||||||
blargg_err_t skip( int n );
|
blargg_err_t skip( int n );
|
||||||
|
|
||||||
virtual ~Data_Reader() { }
|
virtual ~Data_Reader() { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// noncopyable
|
// noncopyable
|
||||||
Data_Reader( const Data_Reader& );
|
Data_Reader( const Data_Reader& );
|
||||||
Data_Reader& operator = ( const Data_Reader& );
|
Data_Reader& operator = ( const Data_Reader& );
|
||||||
|
|
||||||
// Derived interface
|
// Derived interface
|
||||||
protected:
|
protected:
|
||||||
Data_Reader() : remain_( 0 ) { }
|
Data_Reader() : remain_( 0 ) { }
|
||||||
|
|
||||||
// Sets remain
|
// Sets remain
|
||||||
void set_remain( int n ) { assert( n >= 0 ); remain_ = n; }
|
void set_remain( int n ) { assert( n >= 0 ); remain_ = n; }
|
||||||
|
|
||||||
// Do same as read(). Guaranteed that 0 < n <= remain(). Value of remain() is updated
|
// Do same as read(). Guaranteed that 0 < n <= remain(). Value of remain() is updated
|
||||||
// AFTER this call succeeds, not before. set_remain() should NOT be called from this.
|
// AFTER this call succeeds, not before. set_remain() should NOT be called from this.
|
||||||
virtual blargg_err_t read_v( void*, int n ) BLARGG_PURE( { (void)n; return blargg_ok; } )
|
virtual blargg_err_t read_v( void*, int n ) BLARGG_PURE( { (void)n; return blargg_ok; } )
|
||||||
|
|
||||||
// Do same as skip(). Guaranteed that 0 < n <= remain(). Default just reads data
|
// Do same as skip(). Guaranteed that 0 < n <= remain(). Default just reads data
|
||||||
// and discards it. Value of remain() is updated AFTER this call succeeds, not
|
// and discards it. Value of remain() is updated AFTER this call succeeds, not
|
||||||
// before. set_remain() should NOT be called from this.
|
// before. set_remain() should NOT be called from this.
|
||||||
virtual blargg_err_t skip_v( int n );
|
virtual blargg_err_t skip_v( int n );
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
public:
|
public:
|
||||||
BLARGG_DISABLE_NOTHROW
|
BLARGG_DISABLE_NOTHROW
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int remain_;
|
int remain_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Supports seeking in addition to Data_Reader operations
|
// Supports seeking in addition to Data_Reader operations
|
||||||
class File_Reader : public Data_Reader {
|
class File_Reader : public Data_Reader {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Size of file
|
// Size of file
|
||||||
int size() const { return size_; }
|
int size() const { return size_; }
|
||||||
|
|
||||||
// Current position in file
|
// Current position in file
|
||||||
int tell() const { return size_ - remain(); }
|
int tell() const { return size_ - remain(); }
|
||||||
|
|
||||||
// Goes to new position
|
// Goes to new position
|
||||||
blargg_err_t seek( int );
|
blargg_err_t seek( int );
|
||||||
|
|
||||||
// Derived interface
|
// Derived interface
|
||||||
protected:
|
protected:
|
||||||
// Sets size and resets position
|
// Sets size and resets position
|
||||||
void set_size( int n ) { size_ = n; Data_Reader::set_remain( n ); }
|
void set_size( int n ) { size_ = n; Data_Reader::set_remain( n ); }
|
||||||
void set_size( long n ) { set_size( STATIC_CAST(int, n) ); }
|
void set_size( long n ) { set_size( STATIC_CAST(int, n) ); }
|
||||||
|
|
||||||
// Sets reported position
|
// Sets reported position
|
||||||
void set_tell( int i ) { assert( 0 <= i && i <= size_ ); Data_Reader::set_remain( size_ - i ); }
|
void set_tell( int i ) { assert( 0 <= i && i <= size_ ); Data_Reader::set_remain( size_ - i ); }
|
||||||
|
|
||||||
// Do same as seek(). Guaranteed that 0 <= n <= size(). Value of tell() is updated
|
// Do same as seek(). Guaranteed that 0 <= n <= size(). Value of tell() is updated
|
||||||
// AFTER this call succeeds, not before. set_* functions should NOT be called from this.
|
// AFTER this call succeeds, not before. set_* functions should NOT be called from this.
|
||||||
virtual blargg_err_t seek_v( int n ) BLARGG_PURE( { (void)n; return blargg_ok; } )
|
virtual blargg_err_t seek_v( int n ) BLARGG_PURE( { (void)n; return blargg_ok; } )
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
protected:
|
protected:
|
||||||
File_Reader() : size_( 0 ) { }
|
File_Reader() : size_( 0 ) { }
|
||||||
|
|
||||||
virtual blargg_err_t skip_v( int );
|
virtual blargg_err_t skip_v( int );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int size_;
|
int size_;
|
||||||
|
|
||||||
void set_remain(); // avoid accidental use of set_remain
|
void set_remain(); // avoid accidental use of set_remain
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Reads from file on disk
|
// Reads from file on disk
|
||||||
class Std_File_Reader : public File_Reader {
|
class Std_File_Reader : public File_Reader {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Opens file
|
// Opens file
|
||||||
blargg_err_t open( const char path [] );
|
blargg_err_t open( const char path [] );
|
||||||
|
|
||||||
// Closes file if one was open
|
// Closes file if one was open
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
// Switches to unbuffered mode. Useful if buffering is already being
|
// Switches to unbuffered mode. Useful if buffering is already being
|
||||||
// done at a higher level.
|
// done at a higher level.
|
||||||
void make_unbuffered();
|
void make_unbuffered();
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
public:
|
public:
|
||||||
Std_File_Reader();
|
Std_File_Reader();
|
||||||
virtual ~Std_File_Reader();
|
virtual ~Std_File_Reader();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual blargg_err_t read_v( void*, int );
|
virtual blargg_err_t read_v( void*, int );
|
||||||
virtual blargg_err_t seek_v( int );
|
virtual blargg_err_t seek_v( int );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void* file_;
|
void* file_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Treats range of memory as a file
|
// Treats range of memory as a file
|
||||||
class Mem_File_Reader : public File_Reader {
|
class Mem_File_Reader : public File_Reader {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Mem_File_Reader( const void* begin, long size );
|
Mem_File_Reader( const void* begin, long size );
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
protected:
|
protected:
|
||||||
virtual blargg_err_t read_v( void*, int );
|
virtual blargg_err_t read_v( void*, int );
|
||||||
virtual blargg_err_t seek_v( int );
|
virtual blargg_err_t seek_v( int );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char* const begin;
|
const char* const begin;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Allows only count bytes to be read from reader passed
|
// Allows only count bytes to be read from reader passed
|
||||||
class Subset_Reader : public Data_Reader {
|
class Subset_Reader : public Data_Reader {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Subset_Reader( Data_Reader*, int count );
|
Subset_Reader( Data_Reader*, int count );
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
protected:
|
protected:
|
||||||
virtual blargg_err_t read_v( void*, int );
|
virtual blargg_err_t read_v( void*, int );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Data_Reader* const in;
|
Data_Reader* const in;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Joins already-read header and remaining data into original file.
|
// Joins already-read header and remaining data into original file.
|
||||||
// Meant for cases where you've already read header and don't want
|
// Meant for cases where you've already read header and don't want
|
||||||
// to seek and re-read data (for efficiency).
|
// to seek and re-read data (for efficiency).
|
||||||
class Remaining_Reader : public Data_Reader {
|
class Remaining_Reader : public Data_Reader {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Remaining_Reader( void const* header, int header_size, Data_Reader* );
|
Remaining_Reader( void const* header, int header_size, Data_Reader* );
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
protected:
|
protected:
|
||||||
virtual blargg_err_t read_v( void*, int );
|
virtual blargg_err_t read_v( void*, int );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Data_Reader* const in;
|
Data_Reader* const in;
|
||||||
void const* header;
|
void const* header;
|
||||||
int header_remain;
|
int header_remain;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Invokes callback function to read data
|
// Invokes callback function to read data
|
||||||
extern "C" { // necessary to be usable from C
|
extern "C" { // necessary to be usable from C
|
||||||
typedef const char* (*callback_reader_func_t)(
|
typedef const char* (*callback_reader_func_t)(
|
||||||
void* user_data, // Same value passed to constructor
|
void* user_data, // Same value passed to constructor
|
||||||
void* out, // Buffer to place data into
|
void* out, // Buffer to place data into
|
||||||
int count // Number of bytes to read
|
int count // Number of bytes to read
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
class Callback_Reader : public Data_Reader {
|
class Callback_Reader : public Data_Reader {
|
||||||
public:
|
public:
|
||||||
typedef callback_reader_func_t callback_t;
|
typedef callback_reader_func_t callback_t;
|
||||||
Callback_Reader( callback_t, long size, void* user_data );
|
Callback_Reader( callback_t, long size, void* user_data );
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
protected:
|
protected:
|
||||||
virtual blargg_err_t read_v( void*, int );
|
virtual blargg_err_t read_v( void*, int );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
callback_t const callback;
|
callback_t const callback;
|
||||||
void* const user_data;
|
void* const user_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Invokes callback function to read data
|
// Invokes callback function to read data
|
||||||
extern "C" { // necessary to be usable from C
|
extern "C" { // necessary to be usable from C
|
||||||
typedef const char* (*callback_file_reader_func_t)(
|
typedef const char* (*callback_file_reader_func_t)(
|
||||||
void* user_data, // Same value passed to constructor
|
void* user_data, // Same value passed to constructor
|
||||||
void* out, // Buffer to place data into
|
void* out, // Buffer to place data into
|
||||||
int count, // Number of bytes to read
|
int count, // Number of bytes to read
|
||||||
int pos // Position in file to read from
|
int pos // Position in file to read from
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
class Callback_File_Reader : public File_Reader {
|
class Callback_File_Reader : public File_Reader {
|
||||||
public:
|
public:
|
||||||
typedef callback_file_reader_func_t callback_t;
|
typedef callback_file_reader_func_t callback_t;
|
||||||
Callback_File_Reader( callback_t, long size, void* user_data );
|
Callback_File_Reader( callback_t, long size, void* user_data );
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
protected:
|
protected:
|
||||||
virtual blargg_err_t read_v( void*, int );
|
virtual blargg_err_t read_v( void*, int );
|
||||||
virtual blargg_err_t seek_v( int );
|
virtual blargg_err_t seek_v( int );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
callback_t const callback;
|
callback_t const callback;
|
||||||
void* const user_data;
|
void* const user_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_ZLIB_H
|
#ifdef HAVE_ZLIB_H
|
||||||
|
|
||||||
// Reads file compressed with gzip (or uncompressed)
|
// Reads file compressed with gzip (or uncompressed)
|
||||||
class Gzip_File_Reader : public File_Reader {
|
class Gzip_File_Reader : public File_Reader {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Opens possibly gzipped file
|
// Opens possibly gzipped file
|
||||||
blargg_err_t open( const char path [] );
|
blargg_err_t open( const char path [] );
|
||||||
|
|
||||||
// Closes file if one was open
|
// Closes file if one was open
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
public:
|
public:
|
||||||
Gzip_File_Reader();
|
Gzip_File_Reader();
|
||||||
~Gzip_File_Reader();
|
~Gzip_File_Reader();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual blargg_err_t read_v( void*, int );
|
virtual blargg_err_t read_v( void*, int );
|
||||||
virtual blargg_err_t seek_v( int );
|
virtual blargg_err_t seek_v( int );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// void* so "zlib.h" doesn't have to be included here
|
// void* so "zlib.h" doesn't have to be included here
|
||||||
void* file_;
|
void* file_;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char* blargg_to_utf8( const wchar_t* );
|
char* blargg_to_utf8( const wchar_t* );
|
||||||
wchar_t* blargg_to_wide( const char* );
|
wchar_t* blargg_to_wide( const char* );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,341 +1,341 @@
|
||||||
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
||||||
|
|
||||||
#include "File_Extractor.h"
|
#include "File_Extractor.h"
|
||||||
|
|
||||||
/* Copyright (C) 2005-2009 Shay Green. This module is free software; you
|
/* Copyright (C) 2005-2009 Shay Green. This module is free software; you
|
||||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||||
General Public License as published by the Free Software Foundation; either
|
General Public License as published by the Free Software Foundation; either
|
||||||
version 2.1 of the License, or (at your option) any later version. This
|
version 2.1 of the License, or (at your option) any later version. This
|
||||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||||
details. You should have received a copy of the GNU Lesser General Public
|
details. You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this module; if not, write to the Free Software Foundation,
|
License along with this module; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
#include "blargg_source.h"
|
#include "blargg_source.h"
|
||||||
|
|
||||||
File_Extractor::fex_t( fex_type_t t ) :
|
File_Extractor::fex_t( fex_type_t t ) :
|
||||||
type_( t )
|
type_( t )
|
||||||
{
|
{
|
||||||
own_file_ = NULL;
|
own_file_ = NULL;
|
||||||
|
|
||||||
close_();
|
close_();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open
|
// Open
|
||||||
|
|
||||||
blargg_err_t File_Extractor::set_path( const char* path )
|
blargg_err_t File_Extractor::set_path( const char* path )
|
||||||
{
|
{
|
||||||
if ( !path )
|
if ( !path )
|
||||||
path = "";
|
path = "";
|
||||||
|
|
||||||
RETURN_ERR( path_.resize( strlen( path ) + 1 ) );
|
RETURN_ERR( path_.resize( strlen( path ) + 1 ) );
|
||||||
memcpy( path_.begin(), path, path_.size() );
|
memcpy( path_.begin(), path, path_.size() );
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t File_Extractor::open( const char path [] )
|
blargg_err_t File_Extractor::open( const char path [] )
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
|
|
||||||
RETURN_ERR( set_path( path ) );
|
RETURN_ERR( set_path( path ) );
|
||||||
|
|
||||||
blargg_err_t err = open_path_v();
|
blargg_err_t err = open_path_v();
|
||||||
if ( err )
|
if ( err )
|
||||||
close();
|
close();
|
||||||
else
|
else
|
||||||
opened_ = true;
|
opened_ = true;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t File_Extractor::open_path_v()
|
blargg_err_t File_Extractor::open_path_v()
|
||||||
{
|
{
|
||||||
RETURN_ERR( open_arc_file() );
|
RETURN_ERR( open_arc_file() );
|
||||||
|
|
||||||
return open_v();
|
return open_v();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
static void make_unbuffered( Std_File_Reader* r )
|
static void make_unbuffered( Std_File_Reader* r )
|
||||||
{
|
{
|
||||||
r->make_unbuffered();
|
r->make_unbuffered();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
static void make_unbuffered( void* )
|
static void make_unbuffered( void* )
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
blargg_err_t File_Extractor::open_arc_file( bool unbuffered )
|
blargg_err_t File_Extractor::open_arc_file( bool unbuffered )
|
||||||
{
|
{
|
||||||
if ( reader_ )
|
if ( reader_ )
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
|
|
||||||
FEX_FILE_READER* in = BLARGG_NEW FEX_FILE_READER;
|
FEX_FILE_READER* in = BLARGG_NEW FEX_FILE_READER;
|
||||||
CHECK_ALLOC( in );
|
CHECK_ALLOC( in );
|
||||||
|
|
||||||
blargg_err_t err = in->open( arc_path() );
|
blargg_err_t err = in->open( arc_path() );
|
||||||
if ( err )
|
if ( err )
|
||||||
{
|
{
|
||||||
delete in;
|
delete in;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
reader_ = in;
|
reader_ = in;
|
||||||
own_file();
|
own_file();
|
||||||
if ( unbuffered )
|
if ( unbuffered )
|
||||||
make_unbuffered( in );
|
make_unbuffered( in );
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t File_Extractor::open( File_Reader* input, const char* path )
|
blargg_err_t File_Extractor::open( File_Reader* input, const char* path )
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
|
|
||||||
RETURN_ERR( set_path( path ) );
|
RETURN_ERR( set_path( path ) );
|
||||||
|
|
||||||
RETURN_ERR( input->seek( 0 ) );
|
RETURN_ERR( input->seek( 0 ) );
|
||||||
|
|
||||||
reader_ = input;
|
reader_ = input;
|
||||||
blargg_err_t err = open_v();
|
blargg_err_t err = open_v();
|
||||||
if ( err )
|
if ( err )
|
||||||
close();
|
close();
|
||||||
else
|
else
|
||||||
opened_ = true;
|
opened_ = true;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close
|
// Close
|
||||||
|
|
||||||
void File_Extractor::close()
|
void File_Extractor::close()
|
||||||
{
|
{
|
||||||
close_v();
|
close_v();
|
||||||
close_();
|
close_();
|
||||||
}
|
}
|
||||||
|
|
||||||
void File_Extractor::close_()
|
void File_Extractor::close_()
|
||||||
{
|
{
|
||||||
delete own_file_;
|
delete own_file_;
|
||||||
own_file_ = NULL;
|
own_file_ = NULL;
|
||||||
|
|
||||||
tell_ = 0;
|
tell_ = 0;
|
||||||
reader_ = NULL;
|
reader_ = NULL;
|
||||||
opened_ = false;
|
opened_ = false;
|
||||||
|
|
||||||
path_.clear();
|
path_.clear();
|
||||||
clear_file();
|
clear_file();
|
||||||
}
|
}
|
||||||
|
|
||||||
File_Extractor::~fex_t()
|
File_Extractor::~fex_t()
|
||||||
{
|
{
|
||||||
check( !opened() ); // fails if derived destructor didn't call close()
|
check( !opened() ); // fails if derived destructor didn't call close()
|
||||||
|
|
||||||
delete own_file_;
|
delete own_file_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scanning
|
// Scanning
|
||||||
|
|
||||||
void File_Extractor::clear_file()
|
void File_Extractor::clear_file()
|
||||||
{
|
{
|
||||||
name_ = NULL;
|
name_ = NULL;
|
||||||
wname_ = NULL;
|
wname_ = NULL;
|
||||||
done_ = true;
|
done_ = true;
|
||||||
stat_called = false;
|
stat_called = false;
|
||||||
data_ptr_ = NULL;
|
data_ptr_ = NULL;
|
||||||
|
|
||||||
set_info( 0 );
|
set_info( 0 );
|
||||||
own_data_.clear();
|
own_data_.clear();
|
||||||
clear_file_v();
|
clear_file_v();
|
||||||
}
|
}
|
||||||
|
|
||||||
void File_Extractor::set_name( const char new_name [], const wchar_t* new_wname )
|
void File_Extractor::set_name( const char new_name [], const wchar_t* new_wname )
|
||||||
{
|
{
|
||||||
name_ = new_name;
|
name_ = new_name;
|
||||||
wname_ = new_wname;
|
wname_ = new_wname;
|
||||||
done_ = false;
|
done_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void File_Extractor::set_info( int new_size, unsigned date, unsigned crc )
|
void File_Extractor::set_info( int new_size, unsigned date, unsigned crc )
|
||||||
{
|
{
|
||||||
size_ = new_size;
|
size_ = new_size;
|
||||||
date_ = (date != 0xFFFFFFFF ? date : 0);
|
date_ = (date != 0xFFFFFFFF ? date : 0);
|
||||||
crc32_ = crc;
|
crc32_ = crc;
|
||||||
set_remain( new_size );
|
set_remain( new_size );
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t File_Extractor::next_()
|
blargg_err_t File_Extractor::next_()
|
||||||
{
|
{
|
||||||
tell_++;
|
tell_++;
|
||||||
clear_file();
|
clear_file();
|
||||||
|
|
||||||
blargg_err_t err = next_v();
|
blargg_err_t err = next_v();
|
||||||
if ( err )
|
if ( err )
|
||||||
clear_file();
|
clear_file();
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t File_Extractor::next()
|
blargg_err_t File_Extractor::next()
|
||||||
{
|
{
|
||||||
assert( !done() );
|
assert( !done() );
|
||||||
return next_();
|
return next_();
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t File_Extractor::rewind()
|
blargg_err_t File_Extractor::rewind()
|
||||||
{
|
{
|
||||||
assert( opened() );
|
assert( opened() );
|
||||||
|
|
||||||
tell_ = 0;
|
tell_ = 0;
|
||||||
clear_file();
|
clear_file();
|
||||||
|
|
||||||
blargg_err_t err = rewind_v();
|
blargg_err_t err = rewind_v();
|
||||||
if ( err )
|
if ( err )
|
||||||
clear_file();
|
clear_file();
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t File_Extractor::stat()
|
blargg_err_t File_Extractor::stat()
|
||||||
{
|
{
|
||||||
assert( !done() );
|
assert( !done() );
|
||||||
|
|
||||||
if ( !stat_called )
|
if ( !stat_called )
|
||||||
{
|
{
|
||||||
RETURN_ERR( stat_v() );
|
RETURN_ERR( stat_v() );
|
||||||
stat_called = true;
|
stat_called = true;
|
||||||
}
|
}
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell/seek
|
// Tell/seek
|
||||||
|
|
||||||
int const pos_offset = 1;
|
int const pos_offset = 1;
|
||||||
|
|
||||||
fex_pos_t File_Extractor::tell_arc() const
|
fex_pos_t File_Extractor::tell_arc() const
|
||||||
{
|
{
|
||||||
assert( opened() );
|
assert( opened() );
|
||||||
|
|
||||||
fex_pos_t pos = tell_arc_v();
|
fex_pos_t pos = tell_arc_v();
|
||||||
assert( pos >= 0 );
|
assert( pos >= 0 );
|
||||||
|
|
||||||
return pos + pos_offset;
|
return pos + pos_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t File_Extractor::seek_arc( fex_pos_t pos )
|
blargg_err_t File_Extractor::seek_arc( fex_pos_t pos )
|
||||||
{
|
{
|
||||||
assert( opened() );
|
assert( opened() );
|
||||||
assert( pos != 0 );
|
assert( pos != 0 );
|
||||||
|
|
||||||
clear_file();
|
clear_file();
|
||||||
|
|
||||||
blargg_err_t err = seek_arc_v( pos - pos_offset );
|
blargg_err_t err = seek_arc_v( pos - pos_offset );
|
||||||
if ( err )
|
if ( err )
|
||||||
clear_file();
|
clear_file();
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
fex_pos_t File_Extractor::tell_arc_v() const
|
fex_pos_t File_Extractor::tell_arc_v() const
|
||||||
{
|
{
|
||||||
return tell_;
|
return tell_;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t File_Extractor::seek_arc_v( fex_pos_t pos )
|
blargg_err_t File_Extractor::seek_arc_v( fex_pos_t pos )
|
||||||
{
|
{
|
||||||
// >= because seeking to current file should always reset read pointer etc.
|
// >= because seeking to current file should always reset read pointer etc.
|
||||||
if ( tell_ >= pos )
|
if ( tell_ >= pos )
|
||||||
RETURN_ERR( rewind() );
|
RETURN_ERR( rewind() );
|
||||||
|
|
||||||
while ( tell_ < pos )
|
while ( tell_ < pos )
|
||||||
{
|
{
|
||||||
RETURN_ERR( next_() );
|
RETURN_ERR( next_() );
|
||||||
|
|
||||||
if ( done() )
|
if ( done() )
|
||||||
{
|
{
|
||||||
assert( false );
|
assert( false );
|
||||||
return blargg_err_caller;
|
return blargg_err_caller;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert( tell_ == pos );
|
assert( tell_ == pos );
|
||||||
|
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extraction
|
// Extraction
|
||||||
|
|
||||||
blargg_err_t File_Extractor::rewind_file()
|
blargg_err_t File_Extractor::rewind_file()
|
||||||
{
|
{
|
||||||
RETURN_ERR( stat() );
|
RETURN_ERR( stat() );
|
||||||
|
|
||||||
if ( tell() > 0 )
|
if ( tell() > 0 )
|
||||||
{
|
{
|
||||||
if ( data_ptr_ )
|
if ( data_ptr_ )
|
||||||
{
|
{
|
||||||
set_remain( size() );
|
set_remain( size() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RETURN_ERR( seek_arc( tell_arc() ) );
|
RETURN_ERR( seek_arc( tell_arc() ) );
|
||||||
RETURN_ERR( stat() );
|
RETURN_ERR( stat() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t File_Extractor::data( const void** data_out )
|
blargg_err_t File_Extractor::data( const void** data_out )
|
||||||
{
|
{
|
||||||
assert( !done() );
|
assert( !done() );
|
||||||
|
|
||||||
*data_out = NULL;
|
*data_out = NULL;
|
||||||
if ( !data_ptr_ )
|
if ( !data_ptr_ )
|
||||||
{
|
{
|
||||||
int old_tell = tell();
|
int old_tell = tell();
|
||||||
|
|
||||||
RETURN_ERR( rewind_file() );
|
RETURN_ERR( rewind_file() );
|
||||||
|
|
||||||
void const* ptr;
|
void const* ptr;
|
||||||
RETURN_ERR( data_v( &ptr ) );
|
RETURN_ERR( data_v( &ptr ) );
|
||||||
data_ptr_ = ptr;
|
data_ptr_ = ptr;
|
||||||
|
|
||||||
// Now that data is in memory, we can seek by simply setting remain
|
// Now that data is in memory, we can seek by simply setting remain
|
||||||
set_remain( size() - old_tell );
|
set_remain( size() - old_tell );
|
||||||
}
|
}
|
||||||
|
|
||||||
*data_out = data_ptr_;
|
*data_out = data_ptr_;
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t File_Extractor::data_v( void const** out )
|
blargg_err_t File_Extractor::data_v( void const** out )
|
||||||
{
|
{
|
||||||
RETURN_ERR( own_data_.resize( size() ) );
|
RETURN_ERR( own_data_.resize( size() ) );
|
||||||
*out = own_data_.begin();
|
*out = own_data_.begin();
|
||||||
|
|
||||||
blargg_err_t err = extract_v( own_data_.begin(), own_data_.size() );
|
blargg_err_t err = extract_v( own_data_.begin(), own_data_.size() );
|
||||||
if ( err )
|
if ( err )
|
||||||
own_data_.clear();
|
own_data_.clear();
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t File_Extractor::extract_v( void* out, int count )
|
blargg_err_t File_Extractor::extract_v( void* out, int count )
|
||||||
{
|
{
|
||||||
void const* p;
|
void const* p;
|
||||||
RETURN_ERR( data( &p ) );
|
RETURN_ERR( data( &p ) );
|
||||||
memcpy( out, STATIC_CAST(char const*,p) + (size() - remain()), count );
|
memcpy( out, STATIC_CAST(char const*,p) + (size() - remain()), count );
|
||||||
|
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t File_Extractor::read_v( void* out, int count )
|
blargg_err_t File_Extractor::read_v( void* out, int count )
|
||||||
{
|
{
|
||||||
if ( data_ptr_ )
|
if ( data_ptr_ )
|
||||||
return File_Extractor::extract_v( out, count );
|
return File_Extractor::extract_v( out, count );
|
||||||
|
|
||||||
return extract_v( out, count );
|
return extract_v( out, count );
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,191 +1,191 @@
|
||||||
// Compressed file archive interface
|
// Compressed file archive interface
|
||||||
|
|
||||||
// File_Extractor 1.0.0
|
// File_Extractor 1.0.0
|
||||||
#ifndef FILE_EXTRACTOR_H
|
#ifndef FILE_EXTRACTOR_H
|
||||||
#define FILE_EXTRACTOR_H
|
#define FILE_EXTRACTOR_H
|
||||||
|
|
||||||
#include "blargg_common.h"
|
#include "blargg_common.h"
|
||||||
#include "Data_Reader.h"
|
#include "Data_Reader.h"
|
||||||
#include "fex.h"
|
#include "fex.h"
|
||||||
|
|
||||||
struct fex_t : private Data_Reader {
|
struct fex_t : private Data_Reader {
|
||||||
public:
|
public:
|
||||||
virtual ~fex_t();
|
virtual ~fex_t();
|
||||||
|
|
||||||
// Open/close
|
// Open/close
|
||||||
|
|
||||||
// Opens archive from custom data source. Keeps pointer until close().
|
// Opens archive from custom data source. Keeps pointer until close().
|
||||||
blargg_err_t open( File_Reader* input, const char* path = NULL );
|
blargg_err_t open( File_Reader* input, const char* path = NULL );
|
||||||
|
|
||||||
// Takes ownership of File_Reader* passed to open(), so that close()
|
// Takes ownership of File_Reader* passed to open(), so that close()
|
||||||
// will delete it.
|
// will delete it.
|
||||||
void own_file() { own_file_ = reader_; }
|
void own_file() { own_file_ = reader_; }
|
||||||
|
|
||||||
// See fex.h
|
// See fex.h
|
||||||
blargg_err_t open( const char path [] );
|
blargg_err_t open( const char path [] );
|
||||||
fex_type_t type() const { return type_; }
|
fex_type_t type() const { return type_; }
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
// Scanning
|
// Scanning
|
||||||
|
|
||||||
// See fex.h
|
// See fex.h
|
||||||
bool done() const { return done_; }
|
bool done() const { return done_; }
|
||||||
blargg_err_t next();
|
blargg_err_t next();
|
||||||
blargg_err_t rewind();
|
blargg_err_t rewind();
|
||||||
fex_pos_t tell_arc() const;
|
fex_pos_t tell_arc() const;
|
||||||
blargg_err_t seek_arc( fex_pos_t );
|
blargg_err_t seek_arc( fex_pos_t );
|
||||||
|
|
||||||
// Info
|
// Info
|
||||||
|
|
||||||
// See fex.h
|
// See fex.h
|
||||||
const char* name() const { return name_; }
|
const char* name() const { return name_; }
|
||||||
const wchar_t* wname() const { return wname_; }
|
const wchar_t* wname() const { return wname_; }
|
||||||
blargg_err_t stat();
|
blargg_err_t stat();
|
||||||
int size() const { assert( stat_called ); return size_; }
|
int size() const { assert( stat_called ); return size_; }
|
||||||
unsigned int dos_date() const { return date_; }
|
unsigned int dos_date() const { return date_; }
|
||||||
unsigned int crc32() const { return crc32_; }
|
unsigned int crc32() const { return crc32_; }
|
||||||
|
|
||||||
// Extraction
|
// Extraction
|
||||||
|
|
||||||
// Data_Reader to current file's data, so standard Data_Reader interface can
|
// Data_Reader to current file's data, so standard Data_Reader interface can
|
||||||
// be used, rather than having to treat archives specially. stat() must have
|
// be used, rather than having to treat archives specially. stat() must have
|
||||||
// been called.
|
// been called.
|
||||||
Data_Reader& reader() { assert( stat_called ); return *this; }
|
Data_Reader& reader() { assert( stat_called ); return *this; }
|
||||||
|
|
||||||
// See fex.h
|
// See fex.h
|
||||||
blargg_err_t data( const void** data_out );
|
blargg_err_t data( const void** data_out );
|
||||||
int tell() const { return size_ - remain(); }
|
int tell() const { return size_ - remain(); }
|
||||||
|
|
||||||
// Derived interface
|
// Derived interface
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Sets type of object
|
// Sets type of object
|
||||||
fex_t( fex_type_t );
|
fex_t( fex_type_t );
|
||||||
|
|
||||||
// Path to archive file, or "" if none supplied
|
// Path to archive file, or "" if none supplied
|
||||||
const char* arc_path() const { return path_.begin(); }
|
const char* arc_path() const { return path_.begin(); }
|
||||||
|
|
||||||
// Opens archive file if it's not already. If unbuffered is true, opens file
|
// Opens archive file if it's not already. If unbuffered is true, opens file
|
||||||
// without any buffering.
|
// without any buffering.
|
||||||
blargg_err_t open_arc_file( bool unbuffered = false );
|
blargg_err_t open_arc_file( bool unbuffered = false );
|
||||||
|
|
||||||
// Archive file
|
// Archive file
|
||||||
File_Reader& arc() const { return *reader_; }
|
File_Reader& arc() const { return *reader_; }
|
||||||
|
|
||||||
// Sets current file name
|
// Sets current file name
|
||||||
void set_name( const char name [], const wchar_t* wname = NULL );
|
void set_name( const char name [], const wchar_t* wname = NULL );
|
||||||
|
|
||||||
// Sets current file information
|
// Sets current file information
|
||||||
void set_info( int size, unsigned date = 0, unsigned crc = 0 );
|
void set_info( int size, unsigned date = 0, unsigned crc = 0 );
|
||||||
|
|
||||||
// User overrides
|
// User overrides
|
||||||
|
|
||||||
// Overrides must do indicated task. Non-pure functions have reasonable default
|
// Overrides must do indicated task. Non-pure functions have reasonable default
|
||||||
// implementation. Overrides should avoid calling public functions like
|
// implementation. Overrides should avoid calling public functions like
|
||||||
// next() and rewind().
|
// next() and rewind().
|
||||||
|
|
||||||
// Open archive using file_path(). OK to delay actual file opening until later.
|
// Open archive using file_path(). OK to delay actual file opening until later.
|
||||||
// Default just calls open_arc_file(), then open_v().
|
// Default just calls open_arc_file(), then open_v().
|
||||||
virtual blargg_err_t open_path_v();
|
virtual blargg_err_t open_path_v();
|
||||||
|
|
||||||
// Open archive using file() for source data. If unsupported, return error.
|
// Open archive using file() for source data. If unsupported, return error.
|
||||||
virtual blargg_err_t open_v() BLARGG_PURE( ; )
|
virtual blargg_err_t open_v() BLARGG_PURE( ; )
|
||||||
|
|
||||||
// Go to next file in archive and call set_name() and optionally set_info()
|
// Go to next file in archive and call set_name() and optionally set_info()
|
||||||
virtual blargg_err_t next_v() BLARGG_PURE( ; )
|
virtual blargg_err_t next_v() BLARGG_PURE( ; )
|
||||||
|
|
||||||
// Go back to first file in archive
|
// Go back to first file in archive
|
||||||
virtual blargg_err_t rewind_v() BLARGG_PURE( ; )
|
virtual blargg_err_t rewind_v() BLARGG_PURE( ; )
|
||||||
|
|
||||||
// Close archive. Called even if open_path_v() or open_v() return unsuccessfully.
|
// Close archive. Called even if open_path_v() or open_v() return unsuccessfully.
|
||||||
virtual void close_v() BLARGG_PURE( ; )
|
virtual void close_v() BLARGG_PURE( ; )
|
||||||
|
|
||||||
// Clear any fields related to current file
|
// Clear any fields related to current file
|
||||||
virtual void clear_file_v() { }
|
virtual void clear_file_v() { }
|
||||||
|
|
||||||
// Call set_info() if not already called by next_v()
|
// Call set_info() if not already called by next_v()
|
||||||
virtual blargg_err_t stat_v() { return blargg_ok; }
|
virtual blargg_err_t stat_v() { return blargg_ok; }
|
||||||
|
|
||||||
// Return value that allows later return to this file. Result must be >= 0.
|
// Return value that allows later return to this file. Result must be >= 0.
|
||||||
virtual fex_pos_t tell_arc_v() const;
|
virtual fex_pos_t tell_arc_v() const;
|
||||||
|
|
||||||
// Return to previously saved position
|
// Return to previously saved position
|
||||||
virtual blargg_err_t seek_arc_v( fex_pos_t );
|
virtual blargg_err_t seek_arc_v( fex_pos_t );
|
||||||
|
|
||||||
// One or both of the following must be overridden
|
// One or both of the following must be overridden
|
||||||
|
|
||||||
// Provide pointer to data for current file in archive
|
// Provide pointer to data for current file in archive
|
||||||
virtual blargg_err_t data_v( const void** out );
|
virtual blargg_err_t data_v( const void** out );
|
||||||
|
|
||||||
// Extract next n bytes
|
// Extract next n bytes
|
||||||
virtual blargg_err_t extract_v( void* out, int n );
|
virtual blargg_err_t extract_v( void* out, int n );
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
public:
|
public:
|
||||||
BLARGG_DISABLE_NOTHROW
|
BLARGG_DISABLE_NOTHROW
|
||||||
|
|
||||||
private:
|
private:
|
||||||
fex_type_t const type_;
|
fex_type_t const type_;
|
||||||
|
|
||||||
// Archive file
|
// Archive file
|
||||||
blargg_vector<char> path_;
|
blargg_vector<char> path_;
|
||||||
File_Reader* reader_;
|
File_Reader* reader_;
|
||||||
File_Reader* own_file_;
|
File_Reader* own_file_;
|
||||||
bool opened_;
|
bool opened_;
|
||||||
|
|
||||||
// Position in archive
|
// Position in archive
|
||||||
fex_pos_t tell_; // only used by default implementation of tell/seek
|
fex_pos_t tell_; // only used by default implementation of tell/seek
|
||||||
bool done_;
|
bool done_;
|
||||||
|
|
||||||
// Info for current file in archive
|
// Info for current file in archive
|
||||||
const char* name_;
|
const char* name_;
|
||||||
const wchar_t* wname_;
|
const wchar_t* wname_;
|
||||||
unsigned date_;
|
unsigned date_;
|
||||||
unsigned crc32_;
|
unsigned crc32_;
|
||||||
int size_;
|
int size_;
|
||||||
bool stat_called;
|
bool stat_called;
|
||||||
|
|
||||||
// Current file contents
|
// Current file contents
|
||||||
void const* data_ptr_; // NULL if not read into memory
|
void const* data_ptr_; // NULL if not read into memory
|
||||||
blargg_vector<char> own_data_;
|
blargg_vector<char> own_data_;
|
||||||
|
|
||||||
bool opened() const { return opened_; }
|
bool opened() const { return opened_; }
|
||||||
void clear_file();
|
void clear_file();
|
||||||
void close_();
|
void close_();
|
||||||
blargg_err_t set_path( const char* path );
|
blargg_err_t set_path( const char* path );
|
||||||
blargg_err_t rewind_file();
|
blargg_err_t rewind_file();
|
||||||
blargg_err_t next_();
|
blargg_err_t next_();
|
||||||
|
|
||||||
// Data_Reader overrides
|
// Data_Reader overrides
|
||||||
// TODO: override skip_v?
|
// TODO: override skip_v?
|
||||||
virtual blargg_err_t read_v( void* out, int n );
|
virtual blargg_err_t read_v( void* out, int n );
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fex_type_t_
|
struct fex_type_t_
|
||||||
{
|
{
|
||||||
const char* extension;
|
const char* extension;
|
||||||
File_Extractor* (*new_fex)();
|
File_Extractor* (*new_fex)();
|
||||||
const char* name;
|
const char* name;
|
||||||
blargg_err_t (*init)(); // Called by fex_init(). Can be NULL.
|
blargg_err_t (*init)(); // Called by fex_init(). Can be NULL.
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const fex_type_t_
|
extern const fex_type_t_
|
||||||
fex_7z_type [1],
|
fex_7z_type [1],
|
||||||
fex_gz_type [1],
|
fex_gz_type [1],
|
||||||
fex_rar_type [1],
|
fex_rar_type [1],
|
||||||
fex_zip_type [1],
|
fex_zip_type [1],
|
||||||
fex_bin_type [1];
|
fex_bin_type [1];
|
||||||
|
|
||||||
inline blargg_err_t File_Extractor::open_v() { return blargg_ok; }
|
inline blargg_err_t File_Extractor::open_v() { return blargg_ok; }
|
||||||
inline blargg_err_t File_Extractor::next_v() { return blargg_ok; }
|
inline blargg_err_t File_Extractor::next_v() { return blargg_ok; }
|
||||||
inline blargg_err_t File_Extractor::rewind_v() { return blargg_ok; }
|
inline blargg_err_t File_Extractor::rewind_v() { return blargg_ok; }
|
||||||
inline void File_Extractor::close_v() { }
|
inline void File_Extractor::close_v() { }
|
||||||
|
|
||||||
// Default to Std_File_Reader for archive access
|
// Default to Std_File_Reader for archive access
|
||||||
#ifndef FEX_FILE_READER
|
#ifndef FEX_FILE_READER
|
||||||
#define FEX_FILE_READER Std_File_Reader
|
#define FEX_FILE_READER Std_File_Reader
|
||||||
#elif defined (FEX_FILE_READER_INCLUDE)
|
#elif defined (FEX_FILE_READER_INCLUDE)
|
||||||
#include FEX_FILE_READER_INCLUDE
|
#include FEX_FILE_READER_INCLUDE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,98 +1,98 @@
|
||||||
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
||||||
|
|
||||||
#include "Gzip_Extractor.h"
|
#include "Gzip_Extractor.h"
|
||||||
|
|
||||||
/* Copyright (C) 2005-2009 Shay Green. This module is free software; you
|
/* Copyright (C) 2005-2009 Shay Green. This module is free software; you
|
||||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||||
General Public License as published by the Free Software Foundation; either
|
General Public License as published by the Free Software Foundation; either
|
||||||
version 2.1 of the License, or (at your option) any later version. This
|
version 2.1 of the License, or (at your option) any later version. This
|
||||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||||
details. You should have received a copy of the GNU Lesser General Public
|
details. You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this module; if not, write to the Free Software Foundation,
|
License along with this module; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
#include "blargg_source.h"
|
#include "blargg_source.h"
|
||||||
|
|
||||||
// TODO: could close file once data has been read into memory
|
// TODO: could close file once data has been read into memory
|
||||||
|
|
||||||
static blargg_err_t init_gzip_file()
|
static blargg_err_t init_gzip_file()
|
||||||
{
|
{
|
||||||
get_crc_table(); // initialize zlib's CRC-32 tables
|
get_crc_table(); // initialize zlib's CRC-32 tables
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static File_Extractor* new_gzip()
|
static File_Extractor* new_gzip()
|
||||||
{
|
{
|
||||||
return BLARGG_NEW Gzip_Extractor;
|
return BLARGG_NEW Gzip_Extractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
fex_type_t_ const fex_gz_type [1] = {{
|
fex_type_t_ const fex_gz_type [1] = {{
|
||||||
".gz",
|
".gz",
|
||||||
&new_gzip,
|
&new_gzip,
|
||||||
"gzipped file",
|
"gzipped file",
|
||||||
&init_gzip_file
|
&init_gzip_file
|
||||||
}};
|
}};
|
||||||
|
|
||||||
Gzip_Extractor::Gzip_Extractor() :
|
Gzip_Extractor::Gzip_Extractor() :
|
||||||
File_Extractor( fex_gz_type )
|
File_Extractor( fex_gz_type )
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Gzip_Extractor::~Gzip_Extractor()
|
Gzip_Extractor::~Gzip_Extractor()
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Gzip_Extractor::open_path_v()
|
blargg_err_t Gzip_Extractor::open_path_v()
|
||||||
{
|
{
|
||||||
// skip opening file
|
// skip opening file
|
||||||
return open_v();
|
return open_v();
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Gzip_Extractor::stat_v()
|
blargg_err_t Gzip_Extractor::stat_v()
|
||||||
{
|
{
|
||||||
RETURN_ERR( open_arc_file( true ) );
|
RETURN_ERR( open_arc_file( true ) );
|
||||||
if ( !gr.opened() || gr.tell() != 0 )
|
if ( !gr.opened() || gr.tell() != 0 )
|
||||||
RETURN_ERR( gr.open( &arc() ) );
|
RETURN_ERR( gr.open( &arc() ) );
|
||||||
|
|
||||||
set_info( gr.remain(), 0, gr.crc32() );
|
set_info( gr.remain(), 0, gr.crc32() );
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Gzip_Extractor::open_v()
|
blargg_err_t Gzip_Extractor::open_v()
|
||||||
{
|
{
|
||||||
// Remove .gz suffix
|
// Remove .gz suffix
|
||||||
size_t len = strlen( arc_path() );
|
size_t len = strlen( arc_path() );
|
||||||
if ( fex_has_extension( arc_path(), ".gz" ) )
|
if ( fex_has_extension( arc_path(), ".gz" ) )
|
||||||
len -= 3;
|
len -= 3;
|
||||||
|
|
||||||
RETURN_ERR( name.resize( len + 1 ) );
|
RETURN_ERR( name.resize( len + 1 ) );
|
||||||
memcpy( name.begin(), arc_path(), name.size() );
|
memcpy( name.begin(), arc_path(), name.size() );
|
||||||
name [name.size() - 1] = '\0';
|
name [name.size() - 1] = '\0';
|
||||||
|
|
||||||
set_name( name.begin() );
|
set_name( name.begin() );
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gzip_Extractor::close_v()
|
void Gzip_Extractor::close_v()
|
||||||
{
|
{
|
||||||
name.clear();
|
name.clear();
|
||||||
gr.close();
|
gr.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Gzip_Extractor::next_v()
|
blargg_err_t Gzip_Extractor::next_v()
|
||||||
{
|
{
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Gzip_Extractor::rewind_v()
|
blargg_err_t Gzip_Extractor::rewind_v()
|
||||||
{
|
{
|
||||||
set_name( name.begin() );
|
set_name( name.begin() );
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Gzip_Extractor::extract_v( void* p, int n )
|
blargg_err_t Gzip_Extractor::extract_v( void* p, int n )
|
||||||
{
|
{
|
||||||
return gr.read( p, n );
|
return gr.read( p, n );
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,34 @@
|
||||||
// Presents a gzipped file as an "archive" of just that file.
|
// Presents a gzipped file as an "archive" of just that file.
|
||||||
// Also handles non-gzipped files.
|
// Also handles non-gzipped files.
|
||||||
|
|
||||||
// File_Extractor 1.0.0
|
// File_Extractor 1.0.0
|
||||||
#ifndef GZIP_EXTRACTOR_H
|
#ifndef GZIP_EXTRACTOR_H
|
||||||
#define GZIP_EXTRACTOR_H
|
#define GZIP_EXTRACTOR_H
|
||||||
|
|
||||||
#include "File_Extractor.h"
|
#include "File_Extractor.h"
|
||||||
#include "Gzip_Reader.h"
|
#include "Gzip_Reader.h"
|
||||||
|
|
||||||
class Gzip_Extractor : public File_Extractor {
|
class Gzip_Extractor : public File_Extractor {
|
||||||
public:
|
public:
|
||||||
Gzip_Extractor();
|
Gzip_Extractor();
|
||||||
virtual ~Gzip_Extractor();
|
virtual ~Gzip_Extractor();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual blargg_err_t open_path_v();
|
virtual blargg_err_t open_path_v();
|
||||||
virtual blargg_err_t open_v();
|
virtual blargg_err_t open_v();
|
||||||
virtual void close_v();
|
virtual void close_v();
|
||||||
|
|
||||||
virtual blargg_err_t next_v();
|
virtual blargg_err_t next_v();
|
||||||
virtual blargg_err_t rewind_v();
|
virtual blargg_err_t rewind_v();
|
||||||
|
|
||||||
virtual blargg_err_t stat_v();
|
virtual blargg_err_t stat_v();
|
||||||
virtual blargg_err_t extract_v( void*, int );
|
virtual blargg_err_t extract_v( void*, int );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Gzip_Reader gr;
|
Gzip_Reader gr;
|
||||||
blargg_vector<char> name;
|
blargg_vector<char> name;
|
||||||
|
|
||||||
void set_info_();
|
void set_info_();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,85 +1,85 @@
|
||||||
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
||||||
|
|
||||||
#include "Gzip_Reader.h"
|
#include "Gzip_Reader.h"
|
||||||
|
|
||||||
#include "blargg_endian.h"
|
#include "blargg_endian.h"
|
||||||
|
|
||||||
/* Copyright (C) 2006-2009 Shay Green. This module is free software; you
|
/* Copyright (C) 2006-2009 Shay Green. This module is free software; you
|
||||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||||
General Public License as published by the Free Software Foundation; either
|
General Public License as published by the Free Software Foundation; either
|
||||||
version 2.1 of the License, or (at your option) any later version. This
|
version 2.1 of the License, or (at your option) any later version. This
|
||||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||||
details. You should have received a copy of the GNU Lesser General Public
|
details. You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this module; if not, write to the Free Software Foundation,
|
License along with this module; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
#include "blargg_source.h"
|
#include "blargg_source.h"
|
||||||
|
|
||||||
Gzip_Reader::Gzip_Reader()
|
Gzip_Reader::Gzip_Reader()
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
Gzip_Reader::~Gzip_Reader()
|
Gzip_Reader::~Gzip_Reader()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
static blargg_err_t gzip_reader_read( void* file, void* out, int* count )
|
static blargg_err_t gzip_reader_read( void* file, void* out, int* count )
|
||||||
{
|
{
|
||||||
return STATIC_CAST(File_Reader*,file)->read_avail( out, count );
|
return STATIC_CAST(File_Reader*,file)->read_avail( out, count );
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Gzip_Reader::calc_size()
|
blargg_err_t Gzip_Reader::calc_size()
|
||||||
{
|
{
|
||||||
size_ = in->size();
|
size_ = in->size();
|
||||||
crc32_ = 0;
|
crc32_ = 0;
|
||||||
if ( inflater.deflated() )
|
if ( inflater.deflated() )
|
||||||
{
|
{
|
||||||
byte trailer [8];
|
byte trailer [8];
|
||||||
int old_pos = in->tell();
|
int old_pos = in->tell();
|
||||||
RETURN_ERR( in->seek( size_ - sizeof trailer ) );
|
RETURN_ERR( in->seek( size_ - sizeof trailer ) );
|
||||||
RETURN_ERR( in->read( trailer, sizeof trailer ) );
|
RETURN_ERR( in->read( trailer, sizeof trailer ) );
|
||||||
RETURN_ERR( in->seek( old_pos ) );
|
RETURN_ERR( in->seek( old_pos ) );
|
||||||
crc32_ = get_le32( trailer + 0 );
|
crc32_ = get_le32( trailer + 0 );
|
||||||
|
|
||||||
unsigned n = get_le32( trailer + 4 );
|
unsigned n = get_le32( trailer + 4 );
|
||||||
if ( n > INT_MAX )
|
if ( n > INT_MAX )
|
||||||
return BLARGG_ERR( BLARGG_ERR_FILE_FEATURE, "gzip larger than 2GB" );
|
return BLARGG_ERR( BLARGG_ERR_FILE_FEATURE, "gzip larger than 2GB" );
|
||||||
|
|
||||||
size_ = n;
|
size_ = n;
|
||||||
}
|
}
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Gzip_Reader::open( File_Reader* new_in )
|
blargg_err_t Gzip_Reader::open( File_Reader* new_in )
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
|
|
||||||
in = new_in;
|
in = new_in;
|
||||||
RETURN_ERR( in->seek( 0 ) );
|
RETURN_ERR( in->seek( 0 ) );
|
||||||
RETURN_ERR( inflater.begin( gzip_reader_read, new_in ) );
|
RETURN_ERR( inflater.begin( gzip_reader_read, new_in ) );
|
||||||
RETURN_ERR( inflater.set_mode( inflater.mode_auto ) );
|
RETURN_ERR( inflater.set_mode( inflater.mode_auto ) );
|
||||||
RETURN_ERR( calc_size() );
|
RETURN_ERR( calc_size() );
|
||||||
set_remain( size_ );
|
set_remain( size_ );
|
||||||
|
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gzip_Reader::close()
|
void Gzip_Reader::close()
|
||||||
{
|
{
|
||||||
in = NULL;
|
in = NULL;
|
||||||
inflater.end();
|
inflater.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Gzip_Reader::read_v( void* out, int count )
|
blargg_err_t Gzip_Reader::read_v( void* out, int count )
|
||||||
{
|
{
|
||||||
assert( in );
|
assert( in );
|
||||||
int actual = count;
|
int actual = count;
|
||||||
RETURN_ERR( inflater.read( out, &actual ) );
|
RETURN_ERR( inflater.read( out, &actual ) );
|
||||||
|
|
||||||
if ( actual != count )
|
if ( actual != count )
|
||||||
return blargg_err_file_corrupt;
|
return blargg_err_file_corrupt;
|
||||||
|
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,46 +1,46 @@
|
||||||
// Transparently decompresses gzip files, as well as uncompressed
|
// Transparently decompresses gzip files, as well as uncompressed
|
||||||
|
|
||||||
// File_Extractor 1.0.0
|
// File_Extractor 1.0.0
|
||||||
#ifndef GZIP_READER_H
|
#ifndef GZIP_READER_H
|
||||||
#define GZIP_READER_H
|
#define GZIP_READER_H
|
||||||
|
|
||||||
#include "Data_Reader.h"
|
#include "Data_Reader.h"
|
||||||
#include "Zlib_Inflater.h"
|
#include "Zlib_Inflater.h"
|
||||||
|
|
||||||
class Gzip_Reader : public Data_Reader {
|
class Gzip_Reader : public Data_Reader {
|
||||||
public:
|
public:
|
||||||
// Keeps pointer to reader until close(). If
|
// Keeps pointer to reader until close(). If
|
||||||
blargg_err_t open( File_Reader* );
|
blargg_err_t open( File_Reader* );
|
||||||
|
|
||||||
// True if file is open
|
// True if file is open
|
||||||
bool opened() const { return in != NULL; }
|
bool opened() const { return in != NULL; }
|
||||||
|
|
||||||
// Frees memory
|
// Frees memory
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
// True if file is compressed
|
// True if file is compressed
|
||||||
bool deflated() const { return inflater.deflated(); }
|
bool deflated() const { return inflater.deflated(); }
|
||||||
|
|
||||||
// CRC-32 of data, of 0 if unavailable
|
// CRC-32 of data, of 0 if unavailable
|
||||||
unsigned int crc32() const { return crc32_; }
|
unsigned int crc32() const { return crc32_; }
|
||||||
|
|
||||||
// Number of bytes read since opening
|
// Number of bytes read since opening
|
||||||
int tell() const { return size_ - remain(); }
|
int tell() const { return size_ - remain(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Gzip_Reader();
|
Gzip_Reader();
|
||||||
virtual ~Gzip_Reader();
|
virtual ~Gzip_Reader();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual blargg_err_t read_v( void*, int );
|
virtual blargg_err_t read_v( void*, int );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
File_Reader* in;
|
File_Reader* in;
|
||||||
unsigned crc32_;
|
unsigned crc32_;
|
||||||
int size_;
|
int size_;
|
||||||
Zlib_Inflater inflater;
|
Zlib_Inflater inflater;
|
||||||
|
|
||||||
blargg_err_t calc_size();
|
blargg_err_t calc_size();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,197 +1,197 @@
|
||||||
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
||||||
|
|
||||||
#include "blargg_common.h"
|
#include "blargg_common.h"
|
||||||
|
|
||||||
#if FEX_ENABLE_RAR
|
#if FEX_ENABLE_RAR
|
||||||
|
|
||||||
#include "Rar_Extractor.h"
|
#include "Rar_Extractor.h"
|
||||||
|
|
||||||
/* Copyright (C) 2009 Shay Green. This module is free software; you
|
/* Copyright (C) 2009 Shay Green. This module is free software; you
|
||||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||||
General Public License as published by the Free Software Foundation; either
|
General Public License as published by the Free Software Foundation; either
|
||||||
version 2.1 of the License, or (at your option) any later version. This
|
version 2.1 of the License, or (at your option) any later version. This
|
||||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||||
details. You should have received a copy of the GNU Lesser General Public
|
details. You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this module; if not, write to the Free Software Foundation,
|
License along with this module; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
#include "blargg_source.h"
|
#include "blargg_source.h"
|
||||||
|
|
||||||
static blargg_err_t init_rar()
|
static blargg_err_t init_rar()
|
||||||
{
|
{
|
||||||
unrar_init();
|
unrar_init();
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static File_Extractor* new_rar()
|
static File_Extractor* new_rar()
|
||||||
{
|
{
|
||||||
return BLARGG_NEW Rar_Extractor;
|
return BLARGG_NEW Rar_Extractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
fex_type_t_ const fex_rar_type [1] = {{
|
fex_type_t_ const fex_rar_type [1] = {{
|
||||||
".rar",
|
".rar",
|
||||||
&new_rar,
|
&new_rar,
|
||||||
"RAR archive",
|
"RAR archive",
|
||||||
&init_rar
|
&init_rar
|
||||||
}};
|
}};
|
||||||
|
|
||||||
blargg_err_t Rar_Extractor::convert_err( unrar_err_t err )
|
blargg_err_t Rar_Extractor::convert_err( unrar_err_t err )
|
||||||
{
|
{
|
||||||
blargg_err_t reader_err = reader.err;
|
blargg_err_t reader_err = reader.err;
|
||||||
reader.err = blargg_ok;
|
reader.err = blargg_ok;
|
||||||
if ( reader_err )
|
if ( reader_err )
|
||||||
check( err == unrar_next_err );
|
check( err == unrar_next_err );
|
||||||
|
|
||||||
switch ( err )
|
switch ( err )
|
||||||
{
|
{
|
||||||
case unrar_ok: return blargg_ok;
|
case unrar_ok: return blargg_ok;
|
||||||
case unrar_err_memory: return blargg_err_memory;
|
case unrar_err_memory: return blargg_err_memory;
|
||||||
case unrar_err_open: return blargg_err_file_read;
|
case unrar_err_open: return blargg_err_file_read;
|
||||||
case unrar_err_not_arc: return blargg_err_file_type;
|
case unrar_err_not_arc: return blargg_err_file_type;
|
||||||
case unrar_err_corrupt: return blargg_err_file_corrupt;
|
case unrar_err_corrupt: return blargg_err_file_corrupt;
|
||||||
case unrar_err_io: return blargg_err_file_io;
|
case unrar_err_io: return blargg_err_file_io;
|
||||||
case unrar_err_arc_eof: return blargg_err_internal;
|
case unrar_err_arc_eof: return blargg_err_internal;
|
||||||
case unrar_err_encrypted: return BLARGG_ERR( BLARGG_ERR_FILE_FEATURE, "RAR encryption not supported" );
|
case unrar_err_encrypted: return BLARGG_ERR( BLARGG_ERR_FILE_FEATURE, "RAR encryption not supported" );
|
||||||
case unrar_err_segmented: return BLARGG_ERR( BLARGG_ERR_FILE_FEATURE, "RAR segmentation not supported" );
|
case unrar_err_segmented: return BLARGG_ERR( BLARGG_ERR_FILE_FEATURE, "RAR segmentation not supported" );
|
||||||
case unrar_err_huge: return BLARGG_ERR( BLARGG_ERR_FILE_FEATURE, "Huge RAR files not supported" );
|
case unrar_err_huge: return BLARGG_ERR( BLARGG_ERR_FILE_FEATURE, "Huge RAR files not supported" );
|
||||||
case unrar_err_old_algo: return BLARGG_ERR( BLARGG_ERR_FILE_FEATURE, "Old RAR compression not supported" );
|
case unrar_err_old_algo: return BLARGG_ERR( BLARGG_ERR_FILE_FEATURE, "Old RAR compression not supported" );
|
||||||
case unrar_err_new_algo: return BLARGG_ERR( BLARGG_ERR_FILE_FEATURE, "RAR uses unknown newer compression" );
|
case unrar_err_new_algo: return BLARGG_ERR( BLARGG_ERR_FILE_FEATURE, "RAR uses unknown newer compression" );
|
||||||
case unrar_next_err: break;
|
case unrar_next_err: break;
|
||||||
default:
|
default:
|
||||||
check( false ); // unhandled RAR error
|
check( false ); // unhandled RAR error
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( reader_err )
|
if ( reader_err )
|
||||||
return reader_err;
|
return reader_err;
|
||||||
|
|
||||||
check( false );
|
check( false );
|
||||||
return BLARGG_ERR( BLARGG_ERR_INTERNAL, "RAR archive" );
|
return BLARGG_ERR( BLARGG_ERR_INTERNAL, "RAR archive" );
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unrar_err_t handle_err( Rar_Extractor::read_callback_t* h, blargg_err_t err )
|
static inline unrar_err_t handle_err( Rar_Extractor::read_callback_t* h, blargg_err_t err )
|
||||||
{
|
{
|
||||||
if ( !err )
|
if ( !err )
|
||||||
return unrar_ok;
|
return unrar_ok;
|
||||||
|
|
||||||
h->err = err;
|
h->err = err;
|
||||||
return unrar_next_err;
|
return unrar_next_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
static unrar_err_t my_unrar_read( void* data, void* out, int* count, unrar_pos_t pos )
|
static unrar_err_t my_unrar_read( void* data, void* out, int* count, unrar_pos_t pos )
|
||||||
{
|
{
|
||||||
// TODO: 64-bit file support
|
// TODO: 64-bit file support
|
||||||
|
|
||||||
Rar_Extractor::read_callback_t* h = STATIC_CAST(Rar_Extractor::read_callback_t*,data);
|
Rar_Extractor::read_callback_t* h = STATIC_CAST(Rar_Extractor::read_callback_t*,data);
|
||||||
if ( h->pos != pos )
|
if ( h->pos != pos )
|
||||||
{
|
{
|
||||||
blargg_err_t err = h->in->seek( pos );
|
blargg_err_t err = h->in->seek( pos );
|
||||||
if ( err )
|
if ( err )
|
||||||
return handle_err( h, err );
|
return handle_err( h, err );
|
||||||
|
|
||||||
h->pos = pos;
|
h->pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t err = h->in->read_avail( out, count );
|
blargg_err_t err = h->in->read_avail( out, count );
|
||||||
if ( err )
|
if ( err )
|
||||||
return handle_err( h, err );
|
return handle_err( h, err );
|
||||||
|
|
||||||
h->pos += *count;
|
h->pos += *count;
|
||||||
|
|
||||||
return unrar_ok;
|
return unrar_ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rar_Extractor::Rar_Extractor() :
|
Rar_Extractor::Rar_Extractor() :
|
||||||
File_Extractor( fex_rar_type )
|
File_Extractor( fex_rar_type )
|
||||||
{
|
{
|
||||||
unrar = NULL;
|
unrar = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rar_Extractor::~Rar_Extractor()
|
Rar_Extractor::~Rar_Extractor()
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Rar_Extractor::open_v()
|
blargg_err_t Rar_Extractor::open_v()
|
||||||
{
|
{
|
||||||
reader.pos = 0;
|
reader.pos = 0;
|
||||||
reader.in = &arc();
|
reader.in = &arc();
|
||||||
reader.err = blargg_ok;
|
reader.err = blargg_ok;
|
||||||
|
|
||||||
RETURN_ERR( arc().seek( 0 ) );
|
RETURN_ERR( arc().seek( 0 ) );
|
||||||
RETURN_ERR( convert_err( unrar_open_custom( &unrar, &my_unrar_read, &reader ) ) );
|
RETURN_ERR( convert_err( unrar_open_custom( &unrar, &my_unrar_read, &reader ) ) );
|
||||||
return skip_unextractables();
|
return skip_unextractables();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rar_Extractor::close_v()
|
void Rar_Extractor::close_v()
|
||||||
{
|
{
|
||||||
unrar_close( unrar );
|
unrar_close( unrar );
|
||||||
|
|
||||||
unrar = NULL;
|
unrar = NULL;
|
||||||
reader.in = NULL;
|
reader.in = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Rar_Extractor::skip_unextractables()
|
blargg_err_t Rar_Extractor::skip_unextractables()
|
||||||
{
|
{
|
||||||
while ( !unrar_done( unrar ) && unrar_try_extract( unrar ) )
|
while ( !unrar_done( unrar ) && unrar_try_extract( unrar ) )
|
||||||
RETURN_ERR( next_raw() );
|
RETURN_ERR( next_raw() );
|
||||||
|
|
||||||
if ( !unrar_done( unrar ) )
|
if ( !unrar_done( unrar ) )
|
||||||
{
|
{
|
||||||
unrar_info_t const* info = unrar_info( unrar );
|
unrar_info_t const* info = unrar_info( unrar );
|
||||||
|
|
||||||
set_name( info->name, (info->name_w && *info->name_w) ? info->name_w : NULL );
|
set_name( info->name, (info->name_w && *info->name_w) ? info->name_w : NULL );
|
||||||
set_info( info->size, info->dos_date, (info->is_crc32 ? info->crc : 0) );
|
set_info( info->size, info->dos_date, (info->is_crc32 ? info->crc : 0) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Rar_Extractor::next_raw()
|
blargg_err_t Rar_Extractor::next_raw()
|
||||||
{
|
{
|
||||||
return convert_err( unrar_next( unrar ) );
|
return convert_err( unrar_next( unrar ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Rar_Extractor::next_v()
|
blargg_err_t Rar_Extractor::next_v()
|
||||||
{
|
{
|
||||||
RETURN_ERR( next_raw() );
|
RETURN_ERR( next_raw() );
|
||||||
return skip_unextractables();
|
return skip_unextractables();
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Rar_Extractor::rewind_v()
|
blargg_err_t Rar_Extractor::rewind_v()
|
||||||
{
|
{
|
||||||
RETURN_ERR( convert_err( unrar_rewind( unrar ) ) );
|
RETURN_ERR( convert_err( unrar_rewind( unrar ) ) );
|
||||||
return skip_unextractables();
|
return skip_unextractables();
|
||||||
}
|
}
|
||||||
|
|
||||||
fex_pos_t Rar_Extractor::tell_arc_v() const
|
fex_pos_t Rar_Extractor::tell_arc_v() const
|
||||||
{
|
{
|
||||||
return unrar_tell( unrar );
|
return unrar_tell( unrar );
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Rar_Extractor::seek_arc_v( fex_pos_t pos )
|
blargg_err_t Rar_Extractor::seek_arc_v( fex_pos_t pos )
|
||||||
{
|
{
|
||||||
RETURN_ERR( convert_err( unrar_seek( unrar, pos ) ) );
|
RETURN_ERR( convert_err( unrar_seek( unrar, pos ) ) );
|
||||||
return skip_unextractables();
|
return skip_unextractables();
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Rar_Extractor::data_v( void const** out )
|
blargg_err_t Rar_Extractor::data_v( void const** out )
|
||||||
{
|
{
|
||||||
return convert_err( unrar_extract_mem( unrar, out ) );
|
return convert_err( unrar_extract_mem( unrar, out ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Rar_Extractor::extract_v( void* out, int count )
|
blargg_err_t Rar_Extractor::extract_v( void* out, int count )
|
||||||
{
|
{
|
||||||
// We can read entire file directly into user buffer
|
// We can read entire file directly into user buffer
|
||||||
if ( count == size() )
|
if ( count == size() )
|
||||||
return convert_err( unrar_extract( unrar, out, count ) );
|
return convert_err( unrar_extract( unrar, out, count ) );
|
||||||
|
|
||||||
// This will call data_v() and copy from that buffer for us
|
// This will call data_v() and copy from that buffer for us
|
||||||
return File_Extractor::extract_v( out, count );
|
return File_Extractor::extract_v( out, count );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,43 +1,43 @@
|
||||||
// RAR archive extractor
|
// RAR archive extractor
|
||||||
|
|
||||||
// File_Extractor 1.0.0
|
// File_Extractor 1.0.0
|
||||||
#ifndef RAR_EXTRACTOR_H
|
#ifndef RAR_EXTRACTOR_H
|
||||||
#define RAR_EXTRACTOR_H
|
#define RAR_EXTRACTOR_H
|
||||||
|
|
||||||
#include "File_Extractor.h"
|
#include "File_Extractor.h"
|
||||||
#include "unrar/unrar.h"
|
#include "unrar/unrar.h"
|
||||||
|
|
||||||
class Rar_Extractor : public File_Extractor {
|
class Rar_Extractor : public File_Extractor {
|
||||||
public:
|
public:
|
||||||
Rar_Extractor();
|
Rar_Extractor();
|
||||||
virtual ~Rar_Extractor();
|
virtual ~Rar_Extractor();
|
||||||
|
|
||||||
struct read_callback_t
|
struct read_callback_t
|
||||||
{
|
{
|
||||||
const char* err;
|
const char* err;
|
||||||
int pos;
|
int pos;
|
||||||
File_Reader* in;
|
File_Reader* in;
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual blargg_err_t open_v();
|
virtual blargg_err_t open_v();
|
||||||
virtual void close_v();
|
virtual void close_v();
|
||||||
|
|
||||||
virtual blargg_err_t next_v();
|
virtual blargg_err_t next_v();
|
||||||
virtual blargg_err_t rewind_v();
|
virtual blargg_err_t rewind_v();
|
||||||
virtual fex_pos_t tell_arc_v() const;
|
virtual fex_pos_t tell_arc_v() const;
|
||||||
virtual blargg_err_t seek_arc_v( fex_pos_t );
|
virtual blargg_err_t seek_arc_v( fex_pos_t );
|
||||||
|
|
||||||
virtual blargg_err_t data_v( void const** );
|
virtual blargg_err_t data_v( void const** );
|
||||||
virtual blargg_err_t extract_v( void*, int );
|
virtual blargg_err_t extract_v( void*, int );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unrar_t* unrar;
|
unrar_t* unrar;
|
||||||
read_callback_t reader;
|
read_callback_t reader;
|
||||||
|
|
||||||
blargg_err_t convert_err( unrar_err_t );
|
blargg_err_t convert_err( unrar_err_t );
|
||||||
blargg_err_t skip_unextractables();
|
blargg_err_t skip_unextractables();
|
||||||
blargg_err_t next_raw();
|
blargg_err_t next_raw();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,285 +1,285 @@
|
||||||
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
||||||
|
|
||||||
#include "Zip7_Extractor.h"
|
#include "Zip7_Extractor.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "7z_C/7z.h"
|
#include "7z_C/7z.h"
|
||||||
#include "7z_C/7zAlloc.h"
|
#include "7z_C/7zAlloc.h"
|
||||||
#include "7z_C/7zCrc.h"
|
#include "7z_C/7zCrc.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
/* Copyright (C) 2005-2009 Shay Green. This module is free software; you
|
/* Copyright (C) 2005-2009 Shay Green. This module is free software; you
|
||||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||||
General Public License as published by the Free Software Foundation; either
|
General Public License as published by the Free Software Foundation; either
|
||||||
version 2.1 of the License, or (at your option) any later version. This
|
version 2.1 of the License, or (at your option) any later version. This
|
||||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||||
details. You should have received a copy of the GNU Lesser General Public
|
details. You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this module; if not, write to the Free Software Foundation,
|
License along with this module; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
#include "blargg_source.h"
|
#include "blargg_source.h"
|
||||||
|
|
||||||
static ISzAlloc zip7_alloc = { SzAlloc, SzFree };
|
static ISzAlloc zip7_alloc = { SzAlloc, SzFree };
|
||||||
static ISzAlloc zip7_alloc_temp = { SzAllocTemp, SzFreeTemp };
|
static ISzAlloc zip7_alloc_temp = { SzAllocTemp, SzFreeTemp };
|
||||||
|
|
||||||
struct Zip7_Extractor_Impl :
|
struct Zip7_Extractor_Impl :
|
||||||
ISeekInStream
|
ISeekInStream
|
||||||
{
|
{
|
||||||
CLookToRead look;
|
CLookToRead look;
|
||||||
CSzArEx db;
|
CSzArEx db;
|
||||||
|
|
||||||
// SzExtract state
|
// SzExtract state
|
||||||
UInt32 block_index;
|
UInt32 block_index;
|
||||||
Byte* buf;
|
Byte* buf;
|
||||||
size_t buf_size;
|
size_t buf_size;
|
||||||
|
|
||||||
File_Reader* in;
|
File_Reader* in;
|
||||||
const char* in_err;
|
const char* in_err;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
// 7-zip callbacks pass an ISeekInStream* for data, so we must cast it
|
// 7-zip callbacks pass an ISeekInStream* for data, so we must cast it
|
||||||
// back to ISeekInStream* FIRST, then cast to our Impl structure
|
// back to ISeekInStream* FIRST, then cast to our Impl structure
|
||||||
|
|
||||||
static SRes zip7_read_( void* vstream, void* out, size_t* size )
|
static SRes zip7_read_( void* vstream, void* out, size_t* size )
|
||||||
{
|
{
|
||||||
assert( out && size );
|
assert( out && size );
|
||||||
ISeekInStream* stream = STATIC_CAST(ISeekInStream*,vstream);
|
ISeekInStream* stream = STATIC_CAST(ISeekInStream*,vstream);
|
||||||
Zip7_Extractor_Impl* impl = STATIC_CAST(Zip7_Extractor_Impl*,stream);
|
Zip7_Extractor_Impl* impl = STATIC_CAST(Zip7_Extractor_Impl*,stream);
|
||||||
|
|
||||||
long lsize = *size;
|
long lsize = *size;
|
||||||
blargg_err_t err = impl->in->read_avail( out, &lsize );
|
blargg_err_t err = impl->in->read_avail( out, &lsize );
|
||||||
if ( err )
|
if ( err )
|
||||||
{
|
{
|
||||||
*size = 0;
|
*size = 0;
|
||||||
impl->in_err = err;
|
impl->in_err = err;
|
||||||
return SZ_ERROR_READ;
|
return SZ_ERROR_READ;
|
||||||
}
|
}
|
||||||
|
|
||||||
*size = lsize;
|
*size = lsize;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes zip7_seek_( void* vstream, Int64* pos, ESzSeek mode )
|
static SRes zip7_seek_( void* vstream, Int64* pos, ESzSeek mode )
|
||||||
{
|
{
|
||||||
ISeekInStream* stream = STATIC_CAST(ISeekInStream*,vstream);
|
ISeekInStream* stream = STATIC_CAST(ISeekInStream*,vstream);
|
||||||
Zip7_Extractor_Impl* impl = STATIC_CAST(Zip7_Extractor_Impl*,stream);
|
Zip7_Extractor_Impl* impl = STATIC_CAST(Zip7_Extractor_Impl*,stream);
|
||||||
|
|
||||||
// assert( mode != SZ_SEEK_CUR ); // never used
|
// assert( mode != SZ_SEEK_CUR ); // never used
|
||||||
|
|
||||||
if ( mode == SZ_SEEK_END )
|
if ( mode == SZ_SEEK_END )
|
||||||
{
|
{
|
||||||
assert( *pos == 0 ); // only used to find file length
|
assert( *pos == 0 ); // only used to find file length
|
||||||
*pos = impl->in->size();
|
*pos = impl->in->size();
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// assert( mode == SZ_SEEK_SET );
|
// assert( mode == SZ_SEEK_SET );
|
||||||
blargg_err_t err = impl->in->seek( *pos );
|
blargg_err_t err = impl->in->seek( *pos );
|
||||||
if ( err )
|
if ( err )
|
||||||
{
|
{
|
||||||
// don't set in_err in this case, since it might be benign
|
// don't set in_err in this case, since it might be benign
|
||||||
if ( err == blargg_err_file_eof )
|
if ( err == blargg_err_file_eof )
|
||||||
return SZ_ERROR_INPUT_EOF;
|
return SZ_ERROR_INPUT_EOF;
|
||||||
|
|
||||||
impl->in_err = err;
|
impl->in_err = err;
|
||||||
return SZ_ERROR_READ;
|
return SZ_ERROR_READ;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zip7_Extractor::zip7_err( int err )
|
blargg_err_t Zip7_Extractor::zip7_err( int err )
|
||||||
{
|
{
|
||||||
// TODO: ignore in_err in some cases? unsure about which error to use
|
// TODO: ignore in_err in some cases? unsure about which error to use
|
||||||
blargg_err_t in_err = impl->in_err;
|
blargg_err_t in_err = impl->in_err;
|
||||||
impl->in_err = NULL;
|
impl->in_err = NULL;
|
||||||
if ( in_err )
|
if ( in_err )
|
||||||
{
|
{
|
||||||
check( err != SZ_OK );
|
check( err != SZ_OK );
|
||||||
return in_err;
|
return in_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( err )
|
switch ( err )
|
||||||
{
|
{
|
||||||
case SZ_OK: return blargg_ok;
|
case SZ_OK: return blargg_ok;
|
||||||
case SZ_ERROR_MEM: return blargg_err_memory;
|
case SZ_ERROR_MEM: return blargg_err_memory;
|
||||||
case SZ_ERROR_READ: return blargg_err_file_io;
|
case SZ_ERROR_READ: return blargg_err_file_io;
|
||||||
case SZ_ERROR_CRC:
|
case SZ_ERROR_CRC:
|
||||||
case SZ_ERROR_DATA:
|
case SZ_ERROR_DATA:
|
||||||
case SZ_ERROR_INPUT_EOF:
|
case SZ_ERROR_INPUT_EOF:
|
||||||
case SZ_ERROR_ARCHIVE: return blargg_err_file_corrupt;
|
case SZ_ERROR_ARCHIVE: return blargg_err_file_corrupt;
|
||||||
case SZ_ERROR_UNSUPPORTED: return blargg_err_file_feature;
|
case SZ_ERROR_UNSUPPORTED: return blargg_err_file_feature;
|
||||||
case SZ_ERROR_NO_ARCHIVE: return blargg_err_file_type;
|
case SZ_ERROR_NO_ARCHIVE: return blargg_err_file_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
return blargg_err_generic;
|
return blargg_err_generic;
|
||||||
}
|
}
|
||||||
|
|
||||||
static blargg_err_t init_7z()
|
static blargg_err_t init_7z()
|
||||||
{
|
{
|
||||||
static bool inited;
|
static bool inited;
|
||||||
if ( !inited )
|
if ( !inited )
|
||||||
{
|
{
|
||||||
inited = true;
|
inited = true;
|
||||||
CrcGenerateTable();
|
CrcGenerateTable();
|
||||||
}
|
}
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static File_Extractor* new_7z()
|
static File_Extractor* new_7z()
|
||||||
{
|
{
|
||||||
return BLARGG_NEW Zip7_Extractor;
|
return BLARGG_NEW Zip7_Extractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
fex_type_t_ const fex_7z_type [1] = {{
|
fex_type_t_ const fex_7z_type [1] = {{
|
||||||
".7z",
|
".7z",
|
||||||
&new_7z,
|
&new_7z,
|
||||||
"7-zip archive",
|
"7-zip archive",
|
||||||
&init_7z
|
&init_7z
|
||||||
}};
|
}};
|
||||||
|
|
||||||
Zip7_Extractor::Zip7_Extractor() :
|
Zip7_Extractor::Zip7_Extractor() :
|
||||||
File_Extractor( fex_7z_type )
|
File_Extractor( fex_7z_type )
|
||||||
{
|
{
|
||||||
impl = NULL;
|
impl = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Zip7_Extractor::~Zip7_Extractor()
|
Zip7_Extractor::~Zip7_Extractor()
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zip7_Extractor::open_v()
|
blargg_err_t Zip7_Extractor::open_v()
|
||||||
{
|
{
|
||||||
RETURN_ERR( init_7z() );
|
RETURN_ERR( init_7z() );
|
||||||
|
|
||||||
if ( !impl )
|
if ( !impl )
|
||||||
{
|
{
|
||||||
impl = (Zip7_Extractor_Impl*) malloc( sizeof *impl );
|
impl = (Zip7_Extractor_Impl*) malloc( sizeof *impl );
|
||||||
CHECK_ALLOC( impl );
|
CHECK_ALLOC( impl );
|
||||||
}
|
}
|
||||||
|
|
||||||
impl->in = &arc();
|
impl->in = &arc();
|
||||||
impl->block_index = (UInt32) -1;
|
impl->block_index = (UInt32) -1;
|
||||||
impl->buf = NULL;
|
impl->buf = NULL;
|
||||||
impl->buf_size = 0;
|
impl->buf_size = 0;
|
||||||
|
|
||||||
LookToRead_CreateVTable( &impl->look, false );
|
LookToRead_CreateVTable( &impl->look, false );
|
||||||
impl->ISeekInStream::Read = zip7_read_;
|
impl->ISeekInStream::Read = zip7_read_;
|
||||||
impl->ISeekInStream::Seek = zip7_seek_;
|
impl->ISeekInStream::Seek = zip7_seek_;
|
||||||
impl->look.realStream = impl;
|
impl->look.realStream = impl;
|
||||||
LookToRead_Init( &impl->look );
|
LookToRead_Init( &impl->look );
|
||||||
|
|
||||||
SzArEx_Init( &impl->db );
|
SzArEx_Init( &impl->db );
|
||||||
|
|
||||||
impl->in_err = NULL;
|
impl->in_err = NULL;
|
||||||
RETURN_ERR( zip7_err( SzArEx_Open( &impl->db, &impl->look.s,
|
RETURN_ERR( zip7_err( SzArEx_Open( &impl->db, &impl->look.s,
|
||||||
&zip7_alloc, &zip7_alloc_temp ) ) );
|
&zip7_alloc, &zip7_alloc_temp ) ) );
|
||||||
|
|
||||||
return seek_arc_v( 0 );
|
return seek_arc_v( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Zip7_Extractor::close_v()
|
void Zip7_Extractor::close_v()
|
||||||
{
|
{
|
||||||
if ( impl )
|
if ( impl )
|
||||||
{
|
{
|
||||||
if ( impl->in )
|
if ( impl->in )
|
||||||
{
|
{
|
||||||
impl->in = NULL;
|
impl->in = NULL;
|
||||||
SzArEx_Free( &impl->db, &zip7_alloc );
|
SzArEx_Free( &impl->db, &zip7_alloc );
|
||||||
}
|
}
|
||||||
IAlloc_Free( &zip7_alloc, impl->buf );
|
IAlloc_Free( &zip7_alloc, impl->buf );
|
||||||
free( impl );
|
free( impl );
|
||||||
impl = NULL;
|
impl = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zip7_Extractor::next_v()
|
blargg_err_t Zip7_Extractor::next_v()
|
||||||
{
|
{
|
||||||
while ( ++index < (int) impl->db.db.NumFiles )
|
while ( ++index < (int) impl->db.db.NumFiles )
|
||||||
{
|
{
|
||||||
CSzFileItem const& item = impl->db.db.Files [index];
|
CSzFileItem const& item = impl->db.db.Files [index];
|
||||||
if ( !item.IsDir )
|
if ( !item.IsDir )
|
||||||
{
|
{
|
||||||
unsigned long date = 0;
|
unsigned long date = 0;
|
||||||
if ( item.MTimeDefined )
|
if ( item.MTimeDefined )
|
||||||
{
|
{
|
||||||
const UInt64 epoch = ((UInt64)0x019db1de << 32) + 0xd53e8000;
|
const UInt64 epoch = ((UInt64)0x019db1de << 32) + 0xd53e8000;
|
||||||
/* 0x019db1ded53e8000ULL: 1970-01-01 00:00:00 (UTC) */
|
/* 0x019db1ded53e8000ULL: 1970-01-01 00:00:00 (UTC) */
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
|
|
||||||
UInt64 time = ((UInt64)item.MTime.High << 32) + item.MTime.Low - epoch;
|
UInt64 time = ((UInt64)item.MTime.High << 32) + item.MTime.Low - epoch;
|
||||||
time /= 1000000;
|
time /= 1000000;
|
||||||
|
|
||||||
time_t _time = time;
|
time_t _time = time;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
localtime_s( &tm, &_time );
|
localtime_s( &tm, &_time );
|
||||||
#else
|
#else
|
||||||
localtime_r( &_time, &tm );
|
localtime_r( &_time, &tm );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
date = ( tm.tm_sec >> 1 ) & 0x1F |
|
date = ( tm.tm_sec >> 1 ) & 0x1F |
|
||||||
(( tm.tm_min & 0x3F ) << 5 ) |
|
(( tm.tm_min & 0x3F ) << 5 ) |
|
||||||
(( tm.tm_hour & 0x1F ) << 11 ) |
|
(( tm.tm_hour & 0x1F ) << 11 ) |
|
||||||
(( tm.tm_mday & 0x1F ) << 16 ) |
|
(( tm.tm_mday & 0x1F ) << 16 ) |
|
||||||
(( ( tm.tm_mon + 1 ) & 0x0F ) << 21 ) |
|
(( ( tm.tm_mon + 1 ) & 0x0F ) << 21 ) |
|
||||||
(( ( tm.tm_year - 80 ) & 0x7F ) << 25 );
|
(( ( tm.tm_year - 80 ) & 0x7F ) << 25 );
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t name_length = SzArEx_GetFileNameUtf16( &impl->db, index, 0 );
|
size_t name_length = SzArEx_GetFileNameUtf16( &impl->db, index, 0 );
|
||||||
name16.resize( name_length );
|
name16.resize( name_length );
|
||||||
SzArEx_GetFileNameUtf16( &impl->db, index, ( UInt16 * ) name16.begin() );
|
SzArEx_GetFileNameUtf16( &impl->db, index, ( UInt16 * ) name16.begin() );
|
||||||
char * temp = blargg_to_utf8( name16.begin() );
|
char * temp = blargg_to_utf8( name16.begin() );
|
||||||
if ( !temp ) temp = "";
|
if ( !temp ) temp = "";
|
||||||
size_t utf8_length = strlen( temp );
|
size_t utf8_length = strlen( temp );
|
||||||
name8.resize( utf8_length + 1 );
|
name8.resize( utf8_length + 1 );
|
||||||
memcpy( name8.begin(), temp, utf8_length + 1 );
|
memcpy( name8.begin(), temp, utf8_length + 1 );
|
||||||
free( temp );
|
free( temp );
|
||||||
set_name( name8.begin(), name16.begin() );
|
set_name( name8.begin(), name16.begin() );
|
||||||
set_info( item.Size, 0, (item.CrcDefined ? item.Crc : 0) );
|
set_info( item.Size, 0, (item.CrcDefined ? item.Crc : 0) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zip7_Extractor::rewind_v()
|
blargg_err_t Zip7_Extractor::rewind_v()
|
||||||
{
|
{
|
||||||
return seek_arc_v( 0 );
|
return seek_arc_v( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
fex_pos_t Zip7_Extractor::tell_arc_v() const
|
fex_pos_t Zip7_Extractor::tell_arc_v() const
|
||||||
{
|
{
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zip7_Extractor::seek_arc_v( fex_pos_t pos )
|
blargg_err_t Zip7_Extractor::seek_arc_v( fex_pos_t pos )
|
||||||
{
|
{
|
||||||
assert( 0 <= pos && pos <= (int) impl->db.db.NumFiles );
|
assert( 0 <= pos && pos <= (int) impl->db.db.NumFiles );
|
||||||
|
|
||||||
index = pos - 1;
|
index = pos - 1;
|
||||||
return next_v();
|
return next_v();
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zip7_Extractor::data_v( void const** out )
|
blargg_err_t Zip7_Extractor::data_v( void const** out )
|
||||||
{
|
{
|
||||||
impl->in_err = NULL;
|
impl->in_err = NULL;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
RETURN_ERR( zip7_err( SzArEx_Extract( &impl->db, &impl->look.s, index,
|
RETURN_ERR( zip7_err( SzArEx_Extract( &impl->db, &impl->look.s, index,
|
||||||
&impl->block_index, &impl->buf, &impl->buf_size,
|
&impl->block_index, &impl->buf, &impl->buf_size,
|
||||||
&offset, &count, &zip7_alloc, &zip7_alloc_temp ) ) );
|
&offset, &count, &zip7_alloc, &zip7_alloc_temp ) ) );
|
||||||
assert( count == (size_t) size() );
|
assert( count == (size_t) size() );
|
||||||
|
|
||||||
*out = impl->buf + offset;
|
*out = impl->buf + offset;
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
// 7-zip archive extractor
|
// 7-zip archive extractor
|
||||||
|
|
||||||
// File_Extractor 1.0.0
|
// File_Extractor 1.0.0
|
||||||
#ifndef ZIP7_EXTRACTOR_H
|
#ifndef ZIP7_EXTRACTOR_H
|
||||||
#define ZIP7_EXTRACTOR_H
|
#define ZIP7_EXTRACTOR_H
|
||||||
|
|
||||||
#include "File_Extractor.h"
|
#include "File_Extractor.h"
|
||||||
|
|
||||||
struct Zip7_Extractor_Impl;
|
struct Zip7_Extractor_Impl;
|
||||||
|
|
||||||
class Zip7_Extractor : public File_Extractor {
|
class Zip7_Extractor : public File_Extractor {
|
||||||
public:
|
public:
|
||||||
Zip7_Extractor();
|
Zip7_Extractor();
|
||||||
virtual ~Zip7_Extractor();
|
virtual ~Zip7_Extractor();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual blargg_err_t open_v();
|
virtual blargg_err_t open_v();
|
||||||
virtual void close_v();
|
virtual void close_v();
|
||||||
|
|
||||||
virtual blargg_err_t next_v();
|
virtual blargg_err_t next_v();
|
||||||
virtual blargg_err_t rewind_v();
|
virtual blargg_err_t rewind_v();
|
||||||
virtual fex_pos_t tell_arc_v() const;
|
virtual fex_pos_t tell_arc_v() const;
|
||||||
virtual blargg_err_t seek_arc_v( fex_pos_t );
|
virtual blargg_err_t seek_arc_v( fex_pos_t );
|
||||||
|
|
||||||
virtual blargg_err_t data_v( void const** out );
|
virtual blargg_err_t data_v( void const** out );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Zip7_Extractor_Impl* impl;
|
Zip7_Extractor_Impl* impl;
|
||||||
int index;
|
int index;
|
||||||
blargg_vector<char> name8;
|
blargg_vector<char> name8;
|
||||||
blargg_vector<wchar_t> name16;
|
blargg_vector<wchar_t> name16;
|
||||||
|
|
||||||
blargg_err_t zip7_err( int err );
|
blargg_err_t zip7_err( int err );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,390 +1,390 @@
|
||||||
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
||||||
|
|
||||||
#include "Zip_Extractor.h"
|
#include "Zip_Extractor.h"
|
||||||
|
|
||||||
#include "blargg_endian.h"
|
#include "blargg_endian.h"
|
||||||
|
|
||||||
/* Copyright (C) 2005-2009 Shay Green. This module is free software; you
|
/* Copyright (C) 2005-2009 Shay Green. This module is free software; you
|
||||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||||
General Public License as published by the Free Software Foundation; either
|
General Public License as published by the Free Software Foundation; either
|
||||||
version 2.1 of the License, or (at your option) any later version. This
|
version 2.1 of the License, or (at your option) any later version. This
|
||||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||||
details. You should have received a copy of the GNU Lesser General Public
|
details. You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this module; if not, write to the Free Software Foundation,
|
License along with this module; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
/* To avoid copying filename string from catalog, I terminate it by modifying
|
/* To avoid copying filename string from catalog, I terminate it by modifying
|
||||||
catalog data. This potentially requires moving the first byte of the type
|
catalog data. This potentially requires moving the first byte of the type
|
||||||
of the next entry elsewhere; I move it to the first byte of made_by. Kind
|
of the next entry elsewhere; I move it to the first byte of made_by. Kind
|
||||||
of hacky, but I'd rather not have to allocate memory for a copy of it. */
|
of hacky, but I'd rather not have to allocate memory for a copy of it. */
|
||||||
|
|
||||||
#include "blargg_source.h"
|
#include "blargg_source.h"
|
||||||
|
|
||||||
/* Reads this much from end of file when first opening. Only this much is
|
/* Reads this much from end of file when first opening. Only this much is
|
||||||
searched for the end catalog entry. If whole catalog is within this data,
|
searched for the end catalog entry. If whole catalog is within this data,
|
||||||
nothing more needs to be read on open. */
|
nothing more needs to be read on open. */
|
||||||
int const end_read_size = 8 * 1024;
|
int const end_read_size = 8 * 1024;
|
||||||
|
|
||||||
/* Reads are are made using file offset that's a multiple of this,
|
/* Reads are are made using file offset that's a multiple of this,
|
||||||
increasing performance. */
|
increasing performance. */
|
||||||
int const disk_block_size = 4 * 1024;
|
int const disk_block_size = 4 * 1024;
|
||||||
|
|
||||||
// Read buffer used for extracting file data
|
// Read buffer used for extracting file data
|
||||||
int const read_buf_size = 16 * 1024;
|
int const read_buf_size = 16 * 1024;
|
||||||
|
|
||||||
struct header_t
|
struct header_t
|
||||||
{
|
{
|
||||||
char type [4];
|
char type [4];
|
||||||
byte vers [2];
|
byte vers [2];
|
||||||
byte flags [2];
|
byte flags [2];
|
||||||
byte method [2];
|
byte method [2];
|
||||||
byte date [4];
|
byte date [4];
|
||||||
byte crc [4];
|
byte crc [4];
|
||||||
byte raw_size [4];
|
byte raw_size [4];
|
||||||
byte size [4];
|
byte size [4];
|
||||||
byte filename_len [2];
|
byte filename_len [2];
|
||||||
byte extra_len [2];
|
byte extra_len [2];
|
||||||
char filename [2]; // [filename_len]
|
char filename [2]; // [filename_len]
|
||||||
//char extra [extra_len];
|
//char extra [extra_len];
|
||||||
};
|
};
|
||||||
int const header_size = 30;
|
int const header_size = 30;
|
||||||
|
|
||||||
struct entry_t
|
struct entry_t
|
||||||
{
|
{
|
||||||
char type [4];
|
char type [4];
|
||||||
byte made_by [2];
|
byte made_by [2];
|
||||||
byte vers [2];
|
byte vers [2];
|
||||||
byte flags [2];
|
byte flags [2];
|
||||||
byte method [2];
|
byte method [2];
|
||||||
byte date [4];
|
byte date [4];
|
||||||
byte crc [4];
|
byte crc [4];
|
||||||
byte raw_size [4];
|
byte raw_size [4];
|
||||||
byte size [4];
|
byte size [4];
|
||||||
byte filename_len [2];
|
byte filename_len [2];
|
||||||
byte extra_len [2];
|
byte extra_len [2];
|
||||||
byte comment_len [2];
|
byte comment_len [2];
|
||||||
byte disk [2];
|
byte disk [2];
|
||||||
byte int_attrib [2];
|
byte int_attrib [2];
|
||||||
byte ext_attrib [4];
|
byte ext_attrib [4];
|
||||||
byte file_offset [4];
|
byte file_offset [4];
|
||||||
char filename [2]; // [filename_len]
|
char filename [2]; // [filename_len]
|
||||||
//char extra [extra_len];
|
//char extra [extra_len];
|
||||||
//char comment [comment_len];
|
//char comment [comment_len];
|
||||||
};
|
};
|
||||||
int const entry_size = 46;
|
int const entry_size = 46;
|
||||||
|
|
||||||
struct end_entry_t
|
struct end_entry_t
|
||||||
{
|
{
|
||||||
char type [4];
|
char type [4];
|
||||||
byte disk [2];
|
byte disk [2];
|
||||||
byte first_disk [2];
|
byte first_disk [2];
|
||||||
byte disk_entry_count [2];
|
byte disk_entry_count [2];
|
||||||
byte entry_count [2];
|
byte entry_count [2];
|
||||||
byte dir_size [4];
|
byte dir_size [4];
|
||||||
byte dir_offset [4];
|
byte dir_offset [4];
|
||||||
byte comment_len [2];
|
byte comment_len [2];
|
||||||
char comment [2]; // [comment_len]
|
char comment [2]; // [comment_len]
|
||||||
};
|
};
|
||||||
int const end_entry_size = 22;
|
int const end_entry_size = 22;
|
||||||
|
|
||||||
static blargg_err_t init_zip()
|
static blargg_err_t init_zip()
|
||||||
{
|
{
|
||||||
get_crc_table(); // initialize zlib's CRC-32 tables
|
get_crc_table(); // initialize zlib's CRC-32 tables
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static File_Extractor* new_zip()
|
static File_Extractor* new_zip()
|
||||||
{
|
{
|
||||||
return BLARGG_NEW Zip_Extractor;
|
return BLARGG_NEW Zip_Extractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
fex_type_t_ const fex_zip_type [1] = {{
|
fex_type_t_ const fex_zip_type [1] = {{
|
||||||
".zip",
|
".zip",
|
||||||
&new_zip,
|
&new_zip,
|
||||||
"ZIP archive",
|
"ZIP archive",
|
||||||
&init_zip
|
&init_zip
|
||||||
}};
|
}};
|
||||||
|
|
||||||
Zip_Extractor::Zip_Extractor() :
|
Zip_Extractor::Zip_Extractor() :
|
||||||
File_Extractor( fex_zip_type )
|
File_Extractor( fex_zip_type )
|
||||||
{
|
{
|
||||||
Zip_Extractor::clear_file_v();
|
Zip_Extractor::clear_file_v();
|
||||||
|
|
||||||
// If these fail, structures had extra padding inserted by compiler
|
// If these fail, structures had extra padding inserted by compiler
|
||||||
assert( offsetof (header_t,filename) == header_size );
|
assert( offsetof (header_t,filename) == header_size );
|
||||||
assert( offsetof (entry_t,filename) == entry_size );
|
assert( offsetof (entry_t,filename) == entry_size );
|
||||||
assert( offsetof (end_entry_t,comment) == end_entry_size );
|
assert( offsetof (end_entry_t,comment) == end_entry_size );
|
||||||
}
|
}
|
||||||
|
|
||||||
Zip_Extractor::~Zip_Extractor()
|
Zip_Extractor::~Zip_Extractor()
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zip_Extractor::open_path_v()
|
blargg_err_t Zip_Extractor::open_path_v()
|
||||||
{
|
{
|
||||||
RETURN_ERR( open_arc_file( true ) );
|
RETURN_ERR( open_arc_file( true ) );
|
||||||
return File_Extractor::open_path_v();
|
return File_Extractor::open_path_v();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void Zip_Extractor::reorder_entry_header( int offset )
|
void Zip_Extractor::reorder_entry_header( int offset )
|
||||||
{
|
{
|
||||||
catalog [offset + 0] = 0;
|
catalog [offset + 0] = 0;
|
||||||
catalog [offset + 4] = 'P';
|
catalog [offset + 4] = 'P';
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zip_Extractor::open_v()
|
blargg_err_t Zip_Extractor::open_v()
|
||||||
{
|
{
|
||||||
if ( arc().size() < end_entry_size )
|
if ( arc().size() < end_entry_size )
|
||||||
return blargg_err_file_type;
|
return blargg_err_file_type;
|
||||||
|
|
||||||
// Read final end_read_size bytes of file
|
// Read final end_read_size bytes of file
|
||||||
int file_pos = max( 0, arc().size() - end_read_size );
|
int file_pos = max( 0, arc().size() - end_read_size );
|
||||||
file_pos -= file_pos % disk_block_size;
|
file_pos -= file_pos % disk_block_size;
|
||||||
RETURN_ERR( catalog.resize( arc().size() - file_pos ) );
|
RETURN_ERR( catalog.resize( arc().size() - file_pos ) );
|
||||||
RETURN_ERR( arc().seek( file_pos ) );
|
RETURN_ERR( arc().seek( file_pos ) );
|
||||||
RETURN_ERR( arc().read( catalog.begin(), catalog.size() ) );
|
RETURN_ERR( arc().read( catalog.begin(), catalog.size() ) );
|
||||||
|
|
||||||
// Find end-of-catalog entry
|
// Find end-of-catalog entry
|
||||||
int end_pos = catalog.size() - end_entry_size;
|
int end_pos = catalog.size() - end_entry_size;
|
||||||
while ( end_pos >= 0 && memcmp( &catalog [end_pos], "PK\5\6", 4 ) )
|
while ( end_pos >= 0 && memcmp( &catalog [end_pos], "PK\5\6", 4 ) )
|
||||||
end_pos--;
|
end_pos--;
|
||||||
if ( end_pos < 0 )
|
if ( end_pos < 0 )
|
||||||
return blargg_err_file_type;
|
return blargg_err_file_type;
|
||||||
end_entry_t const& end_entry = (end_entry_t&) catalog [end_pos];
|
end_entry_t const& end_entry = (end_entry_t&) catalog [end_pos];
|
||||||
end_pos += file_pos;
|
end_pos += file_pos;
|
||||||
|
|
||||||
// some idiotic zip compressors add data to end of zip without setting comment len
|
// some idiotic zip compressors add data to end of zip without setting comment len
|
||||||
// check( arc().size() == end_pos + end_entry_size + get_le16( end_entry.comment_len ) );
|
// check( arc().size() == end_pos + end_entry_size + get_le16( end_entry.comment_len ) );
|
||||||
|
|
||||||
// Find file offset of beginning of catalog
|
// Find file offset of beginning of catalog
|
||||||
catalog_begin = get_le32( end_entry.dir_offset );
|
catalog_begin = get_le32( end_entry.dir_offset );
|
||||||
int catalog_size = end_pos - catalog_begin;
|
int catalog_size = end_pos - catalog_begin;
|
||||||
if ( catalog_size < 0 )
|
if ( catalog_size < 0 )
|
||||||
return blargg_err_file_corrupt;
|
return blargg_err_file_corrupt;
|
||||||
catalog_size += end_entry_size;
|
catalog_size += end_entry_size;
|
||||||
|
|
||||||
// See if catalog is entirely contained in bytes already read
|
// See if catalog is entirely contained in bytes already read
|
||||||
int begin_offset = catalog_begin - file_pos;
|
int begin_offset = catalog_begin - file_pos;
|
||||||
if ( begin_offset >= 0 )
|
if ( begin_offset >= 0 )
|
||||||
memmove( catalog.begin(), &catalog [begin_offset], catalog_size );
|
memmove( catalog.begin(), &catalog [begin_offset], catalog_size );
|
||||||
|
|
||||||
RETURN_ERR( catalog.resize( catalog_size ) );
|
RETURN_ERR( catalog.resize( catalog_size ) );
|
||||||
if ( begin_offset < 0 )
|
if ( begin_offset < 0 )
|
||||||
{
|
{
|
||||||
// Catalog begins before bytes read, so it needs to be read
|
// Catalog begins before bytes read, so it needs to be read
|
||||||
RETURN_ERR( arc().seek( catalog_begin ) );
|
RETURN_ERR( arc().seek( catalog_begin ) );
|
||||||
RETURN_ERR( arc().read( catalog.begin(), catalog.size() ) );
|
RETURN_ERR( arc().read( catalog.begin(), catalog.size() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// First entry in catalog should be a file or end of archive
|
// First entry in catalog should be a file or end of archive
|
||||||
if ( memcmp( catalog.begin(), "PK\1\2", 4 ) && memcmp( catalog.begin(), "PK\5\6", 4 ) )
|
if ( memcmp( catalog.begin(), "PK\1\2", 4 ) && memcmp( catalog.begin(), "PK\5\6", 4 ) )
|
||||||
return blargg_err_file_type;
|
return blargg_err_file_type;
|
||||||
|
|
||||||
reorder_entry_header( 0 );
|
reorder_entry_header( 0 );
|
||||||
return rewind_v();
|
return rewind_v();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Zip_Extractor::close_v()
|
void Zip_Extractor::close_v()
|
||||||
{
|
{
|
||||||
catalog.clear();
|
catalog.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scanning
|
// Scanning
|
||||||
|
|
||||||
inline
|
inline
|
||||||
static bool is_normal_file( entry_t const& e, unsigned len )
|
static bool is_normal_file( entry_t const& e, unsigned len )
|
||||||
{
|
{
|
||||||
int last_char = (len ? e.filename [len - 1] : '/');
|
int last_char = (len ? e.filename [len - 1] : '/');
|
||||||
bool is_dir = (last_char == '/' || last_char == '\\');
|
bool is_dir = (last_char == '/' || last_char == '\\');
|
||||||
if ( is_dir && get_le32( e.size ) == 0 )
|
if ( is_dir && get_le32( e.size ) == 0 )
|
||||||
return false;
|
return false;
|
||||||
check( !is_dir );
|
check( !is_dir );
|
||||||
|
|
||||||
// Mac OS X puts meta-information in separate files with normal extensions,
|
// Mac OS X puts meta-information in separate files with normal extensions,
|
||||||
// so they must be filtered out or caller will mistake them for normal files.
|
// so they must be filtered out or caller will mistake them for normal files.
|
||||||
if ( e.made_by[1] == 3 )
|
if ( e.made_by[1] == 3 )
|
||||||
{
|
{
|
||||||
const char* dir = strrchr( e.filename, '/' );
|
const char* dir = strrchr( e.filename, '/' );
|
||||||
if ( dir )
|
if ( dir )
|
||||||
dir++;
|
dir++;
|
||||||
else
|
else
|
||||||
dir = e.filename;
|
dir = e.filename;
|
||||||
|
|
||||||
if ( *dir == '.' )
|
if ( *dir == '.' )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( !strcmp( dir, "Icon\x0D" ) )
|
if ( !strcmp( dir, "Icon\x0D" ) )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zip_Extractor::update_info( bool advance_first )
|
blargg_err_t Zip_Extractor::update_info( bool advance_first )
|
||||||
{
|
{
|
||||||
while ( 1 )
|
while ( 1 )
|
||||||
{
|
{
|
||||||
entry_t& e = (entry_t&) catalog [catalog_pos];
|
entry_t& e = (entry_t&) catalog [catalog_pos];
|
||||||
|
|
||||||
if ( memcmp( e.type, "\0K\1\2P", 5 ) && memcmp( e.type, "PK\1\2", 4 ) )
|
if ( memcmp( e.type, "\0K\1\2P", 5 ) && memcmp( e.type, "PK\1\2", 4 ) )
|
||||||
{
|
{
|
||||||
check( !memcmp( e.type, "\0K\5\6P", 5 ) );
|
check( !memcmp( e.type, "\0K\5\6P", 5 ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned len = get_le16( e.filename_len );
|
unsigned len = get_le16( e.filename_len );
|
||||||
int next_offset = catalog_pos + entry_size + len + get_le16( e.extra_len ) +
|
int next_offset = catalog_pos + entry_size + len + get_le16( e.extra_len ) +
|
||||||
get_le16( e.comment_len );
|
get_le16( e.comment_len );
|
||||||
if ( (unsigned) next_offset > catalog.size() - end_entry_size )
|
if ( (unsigned) next_offset > catalog.size() - end_entry_size )
|
||||||
return blargg_err_file_corrupt;
|
return blargg_err_file_corrupt;
|
||||||
|
|
||||||
if ( catalog [next_offset] == 'P' )
|
if ( catalog [next_offset] == 'P' )
|
||||||
reorder_entry_header( next_offset );
|
reorder_entry_header( next_offset );
|
||||||
|
|
||||||
if ( !advance_first )
|
if ( !advance_first )
|
||||||
{
|
{
|
||||||
e.filename [len] = 0; // terminate name
|
e.filename [len] = 0; // terminate name
|
||||||
|
|
||||||
if ( is_normal_file( e, len ) )
|
if ( is_normal_file( e, len ) )
|
||||||
{
|
{
|
||||||
set_name( e.filename );
|
set_name( e.filename );
|
||||||
set_info( get_le32( e.size ), get_le32( e.date ), get_le32( e.crc ) );
|
set_info( get_le32( e.size ), get_le32( e.date ), get_le32( e.crc ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
catalog_pos = next_offset;
|
catalog_pos = next_offset;
|
||||||
advance_first = false;
|
advance_first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zip_Extractor::next_v()
|
blargg_err_t Zip_Extractor::next_v()
|
||||||
{
|
{
|
||||||
return update_info( true );
|
return update_info( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zip_Extractor::rewind_v()
|
blargg_err_t Zip_Extractor::rewind_v()
|
||||||
{
|
{
|
||||||
return seek_arc_v( 0 );
|
return seek_arc_v( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
fex_pos_t Zip_Extractor::tell_arc_v() const
|
fex_pos_t Zip_Extractor::tell_arc_v() const
|
||||||
{
|
{
|
||||||
return catalog_pos;
|
return catalog_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zip_Extractor::seek_arc_v( fex_pos_t pos )
|
blargg_err_t Zip_Extractor::seek_arc_v( fex_pos_t pos )
|
||||||
{
|
{
|
||||||
assert( 0 <= pos && (size_t) pos <= catalog.size() - end_entry_size );
|
assert( 0 <= pos && (size_t) pos <= catalog.size() - end_entry_size );
|
||||||
|
|
||||||
catalog_pos = pos;
|
catalog_pos = pos;
|
||||||
return update_info( false );
|
return update_info( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reading
|
// Reading
|
||||||
|
|
||||||
void Zip_Extractor::clear_file_v()
|
void Zip_Extractor::clear_file_v()
|
||||||
{
|
{
|
||||||
buf.end();
|
buf.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zip_Extractor::inflater_read( void* data, void* out, int* count )
|
blargg_err_t Zip_Extractor::inflater_read( void* data, void* out, int* count )
|
||||||
{
|
{
|
||||||
Zip_Extractor& self = *STATIC_CAST(Zip_Extractor*,data);
|
Zip_Extractor& self = *STATIC_CAST(Zip_Extractor*,data);
|
||||||
|
|
||||||
if ( *count > self.raw_remain )
|
if ( *count > self.raw_remain )
|
||||||
*count = self.raw_remain;
|
*count = self.raw_remain;
|
||||||
|
|
||||||
self.raw_remain -= *count;
|
self.raw_remain -= *count;
|
||||||
|
|
||||||
return self.arc().read( out, *count );
|
return self.arc().read( out, *count );
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zip_Extractor::fill_buf( int offset, int buf_size, int initial_read )
|
blargg_err_t Zip_Extractor::fill_buf( int offset, int buf_size, int initial_read )
|
||||||
{
|
{
|
||||||
raw_remain = arc().size() - offset;
|
raw_remain = arc().size() - offset;
|
||||||
RETURN_ERR( arc().seek( offset ) );
|
RETURN_ERR( arc().seek( offset ) );
|
||||||
return buf.begin( inflater_read, this, buf_size, initial_read );
|
return buf.begin( inflater_read, this, buf_size, initial_read );
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zip_Extractor::first_read( int count )
|
blargg_err_t Zip_Extractor::first_read( int count )
|
||||||
{
|
{
|
||||||
entry_t const& e = (entry_t&) catalog [catalog_pos];
|
entry_t const& e = (entry_t&) catalog [catalog_pos];
|
||||||
|
|
||||||
// Determine compression
|
// Determine compression
|
||||||
{
|
{
|
||||||
int method = get_le16( e.method );
|
int method = get_le16( e.method );
|
||||||
if ( (method && method != Z_DEFLATED) || get_le16( e.vers ) > 20 )
|
if ( (method && method != Z_DEFLATED) || get_le16( e.vers ) > 20 )
|
||||||
return BLARGG_ERR( BLARGG_ERR_FILE_FEATURE, "compression method" );
|
return BLARGG_ERR( BLARGG_ERR_FILE_FEATURE, "compression method" );
|
||||||
file_deflated = (method != 0);
|
file_deflated = (method != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int raw_size = get_le32( e.raw_size );
|
int raw_size = get_le32( e.raw_size );
|
||||||
|
|
||||||
int file_offset = get_le32( e.file_offset );
|
int file_offset = get_le32( e.file_offset );
|
||||||
int align = file_offset % disk_block_size;
|
int align = file_offset % disk_block_size;
|
||||||
{
|
{
|
||||||
// read header
|
// read header
|
||||||
int buf_size = 3 * disk_block_size - 1 + raw_size; // space for all raw data
|
int buf_size = 3 * disk_block_size - 1 + raw_size; // space for all raw data
|
||||||
buf_size -= buf_size % disk_block_size;
|
buf_size -= buf_size % disk_block_size;
|
||||||
int initial_read = buf_size;
|
int initial_read = buf_size;
|
||||||
if ( !file_deflated || count < size() )
|
if ( !file_deflated || count < size() )
|
||||||
{
|
{
|
||||||
buf_size = read_buf_size;
|
buf_size = read_buf_size;
|
||||||
initial_read = disk_block_size * 2;
|
initial_read = disk_block_size * 2;
|
||||||
}
|
}
|
||||||
// TODO: avoid re-reading if buffer already has data we want?
|
// TODO: avoid re-reading if buffer already has data we want?
|
||||||
RETURN_ERR( fill_buf( file_offset - align, buf_size, initial_read ) );
|
RETURN_ERR( fill_buf( file_offset - align, buf_size, initial_read ) );
|
||||||
}
|
}
|
||||||
header_t const& h = (header_t&) buf.data() [align];
|
header_t const& h = (header_t&) buf.data() [align];
|
||||||
if ( buf.filled() < align + header_size || memcmp( h.type, "PK\3\4", 4 ) )
|
if ( buf.filled() < align + header_size || memcmp( h.type, "PK\3\4", 4 ) )
|
||||||
return blargg_err_file_corrupt;
|
return blargg_err_file_corrupt;
|
||||||
|
|
||||||
// CRCs of header and file data
|
// CRCs of header and file data
|
||||||
correct_crc = get_le32( h.crc );
|
correct_crc = get_le32( h.crc );
|
||||||
if ( !correct_crc )
|
if ( !correct_crc )
|
||||||
correct_crc = get_le32( e.crc );
|
correct_crc = get_le32( e.crc );
|
||||||
check( correct_crc == get_le32( e.crc ) ); // catalog CRC should match
|
check( correct_crc == get_le32( e.crc ) ); // catalog CRC should match
|
||||||
crc = ::crc32( 0, NULL, 0 );
|
crc = ::crc32( 0, NULL, 0 );
|
||||||
|
|
||||||
// Data offset
|
// Data offset
|
||||||
int data_offset = file_offset + header_size +
|
int data_offset = file_offset + header_size +
|
||||||
get_le16( h.filename_len ) + get_le16( h.extra_len );
|
get_le16( h.filename_len ) + get_le16( h.extra_len );
|
||||||
if ( data_offset + raw_size > catalog_begin )
|
if ( data_offset + raw_size > catalog_begin )
|
||||||
return blargg_err_file_corrupt;
|
return blargg_err_file_corrupt;
|
||||||
|
|
||||||
// Refill buffer if there's lots of extra data after header
|
// Refill buffer if there's lots of extra data after header
|
||||||
int buf_offset = data_offset - file_offset + align;
|
int buf_offset = data_offset - file_offset + align;
|
||||||
if ( buf_offset > buf.filled() )
|
if ( buf_offset > buf.filled() )
|
||||||
{
|
{
|
||||||
// TODO: this will almost never occur, making it a good place for bugs
|
// TODO: this will almost never occur, making it a good place for bugs
|
||||||
buf_offset = data_offset % disk_block_size;
|
buf_offset = data_offset % disk_block_size;
|
||||||
RETURN_ERR( fill_buf( data_offset - buf_offset, read_buf_size, disk_block_size ) );
|
RETURN_ERR( fill_buf( data_offset - buf_offset, read_buf_size, disk_block_size ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_remain = raw_size - (buf.filled() - buf_offset);
|
raw_remain = raw_size - (buf.filled() - buf_offset);
|
||||||
return buf.set_mode( (file_deflated ? buf.mode_raw_deflate : buf.mode_copy), buf_offset );
|
return buf.set_mode( (file_deflated ? buf.mode_raw_deflate : buf.mode_copy), buf_offset );
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zip_Extractor::extract_v( void* out, int count )
|
blargg_err_t Zip_Extractor::extract_v( void* out, int count )
|
||||||
{
|
{
|
||||||
if ( tell() == 0 )
|
if ( tell() == 0 )
|
||||||
RETURN_ERR( first_read( count ) );
|
RETURN_ERR( first_read( count ) );
|
||||||
|
|
||||||
int actual = count;
|
int actual = count;
|
||||||
RETURN_ERR( buf.read( out, &actual ) );
|
RETURN_ERR( buf.read( out, &actual ) );
|
||||||
if ( actual < count )
|
if ( actual < count )
|
||||||
return blargg_err_file_corrupt;
|
return blargg_err_file_corrupt;
|
||||||
|
|
||||||
crc = ::crc32( crc, (byte const*) out, count );
|
crc = ::crc32( crc, (byte const*) out, count );
|
||||||
if ( count == reader().remain() && crc != correct_crc )
|
if ( count == reader().remain() && crc != correct_crc )
|
||||||
return blargg_err_file_corrupt;
|
return blargg_err_file_corrupt;
|
||||||
|
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +1,45 @@
|
||||||
// ZIP archive extractor. Only supports deflation and store (no compression).
|
// ZIP archive extractor. Only supports deflation and store (no compression).
|
||||||
|
|
||||||
// File_Extractor 1.0.0
|
// File_Extractor 1.0.0
|
||||||
#ifndef ZIP_EXTRACTOR_H
|
#ifndef ZIP_EXTRACTOR_H
|
||||||
#define ZIP_EXTRACTOR_H
|
#define ZIP_EXTRACTOR_H
|
||||||
|
|
||||||
#include "File_Extractor.h"
|
#include "File_Extractor.h"
|
||||||
#include "Zlib_Inflater.h"
|
#include "Zlib_Inflater.h"
|
||||||
|
|
||||||
class Zip_Extractor : public File_Extractor {
|
class Zip_Extractor : public File_Extractor {
|
||||||
public:
|
public:
|
||||||
Zip_Extractor();
|
Zip_Extractor();
|
||||||
virtual ~Zip_Extractor();
|
virtual ~Zip_Extractor();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual blargg_err_t open_path_v();
|
virtual blargg_err_t open_path_v();
|
||||||
virtual blargg_err_t open_v();
|
virtual blargg_err_t open_v();
|
||||||
virtual void close_v();
|
virtual void close_v();
|
||||||
|
|
||||||
virtual void clear_file_v();
|
virtual void clear_file_v();
|
||||||
virtual blargg_err_t next_v();
|
virtual blargg_err_t next_v();
|
||||||
virtual blargg_err_t rewind_v();
|
virtual blargg_err_t rewind_v();
|
||||||
virtual fex_pos_t tell_arc_v() const;
|
virtual fex_pos_t tell_arc_v() const;
|
||||||
virtual blargg_err_t seek_arc_v( fex_pos_t );
|
virtual blargg_err_t seek_arc_v( fex_pos_t );
|
||||||
|
|
||||||
virtual blargg_err_t extract_v( void*, int );
|
virtual blargg_err_t extract_v( void*, int );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
blargg_vector<char> catalog;
|
blargg_vector<char> catalog;
|
||||||
int catalog_begin; // offset of first catalog entry in file (to detect corruption)
|
int catalog_begin; // offset of first catalog entry in file (to detect corruption)
|
||||||
int catalog_pos; // position of current entry in catalog
|
int catalog_pos; // position of current entry in catalog
|
||||||
int raw_remain; // bytes remaining to be read from zip file for current file
|
int raw_remain; // bytes remaining to be read from zip file for current file
|
||||||
unsigned crc; // ongoing CRC of extracted bytes
|
unsigned crc; // ongoing CRC of extracted bytes
|
||||||
unsigned correct_crc;
|
unsigned correct_crc;
|
||||||
bool file_deflated;
|
bool file_deflated;
|
||||||
Zlib_Inflater buf;
|
Zlib_Inflater buf;
|
||||||
|
|
||||||
blargg_err_t fill_buf( int offset, int buf_size, int initial_read );
|
blargg_err_t fill_buf( int offset, int buf_size, int initial_read );
|
||||||
blargg_err_t update_info( bool advance_first );
|
blargg_err_t update_info( bool advance_first );
|
||||||
blargg_err_t first_read( int count );
|
blargg_err_t first_read( int count );
|
||||||
void reorder_entry_header( int offset );
|
void reorder_entry_header( int offset );
|
||||||
static blargg_err_t inflater_read( void* data, void* out, int* count );
|
static blargg_err_t inflater_read( void* data, void* out, int* count );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,257 +1,257 @@
|
||||||
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
||||||
|
|
||||||
#include "Zlib_Inflater.h"
|
#include "Zlib_Inflater.h"
|
||||||
|
|
||||||
/* Copyright (C) 2006-2009 Shay Green. This module is free software; you
|
/* Copyright (C) 2006-2009 Shay Green. This module is free software; you
|
||||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||||
General Public License as published by the Free Software Foundation; either
|
General Public License as published by the Free Software Foundation; either
|
||||||
version 2.1 of the License, or (at your option) any later version. This
|
version 2.1 of the License, or (at your option) any later version. This
|
||||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||||
details. You should have received a copy of the GNU Lesser General Public
|
details. You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this module; if not, write to the Free Software Foundation,
|
License along with this module; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
#include "blargg_source.h"
|
#include "blargg_source.h"
|
||||||
|
|
||||||
int const block_size = 4096;
|
int const block_size = 4096;
|
||||||
|
|
||||||
static const char* get_zlib_err( int code )
|
static const char* get_zlib_err( int code )
|
||||||
{
|
{
|
||||||
assert( code != Z_OK );
|
assert( code != Z_OK );
|
||||||
switch ( code )
|
switch ( code )
|
||||||
{
|
{
|
||||||
case Z_MEM_ERROR: return blargg_err_memory;
|
case Z_MEM_ERROR: return blargg_err_memory;
|
||||||
case Z_DATA_ERROR: return blargg_err_file_corrupt;
|
case Z_DATA_ERROR: return blargg_err_file_corrupt;
|
||||||
// TODO: handle more error codes
|
// TODO: handle more error codes
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* str = zError( code );
|
const char* str = zError( code );
|
||||||
if ( !str )
|
if ( !str )
|
||||||
str = BLARGG_ERR( BLARGG_ERR_GENERIC, "problem unzipping data" );
|
str = BLARGG_ERR( BLARGG_ERR_GENERIC, "problem unzipping data" );
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Zlib_Inflater::end()
|
void Zlib_Inflater::end()
|
||||||
{
|
{
|
||||||
if ( deflated_ )
|
if ( deflated_ )
|
||||||
{
|
{
|
||||||
deflated_ = false;
|
deflated_ = false;
|
||||||
if ( inflateEnd( &zbuf ) )
|
if ( inflateEnd( &zbuf ) )
|
||||||
check( false );
|
check( false );
|
||||||
}
|
}
|
||||||
buf.clear();
|
buf.clear();
|
||||||
|
|
||||||
static z_stream const empty = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
static z_stream const empty = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
memcpy( &zbuf, &empty, sizeof zbuf );
|
memcpy( &zbuf, &empty, sizeof zbuf );
|
||||||
}
|
}
|
||||||
|
|
||||||
Zlib_Inflater::Zlib_Inflater()
|
Zlib_Inflater::Zlib_Inflater()
|
||||||
{
|
{
|
||||||
deflated_ = false;
|
deflated_ = false;
|
||||||
end(); // initialize things
|
end(); // initialize things
|
||||||
}
|
}
|
||||||
|
|
||||||
Zlib_Inflater::~Zlib_Inflater()
|
Zlib_Inflater::~Zlib_Inflater()
|
||||||
{
|
{
|
||||||
end();
|
end();
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zlib_Inflater::fill_buf( int count )
|
blargg_err_t Zlib_Inflater::fill_buf( int count )
|
||||||
{
|
{
|
||||||
byte* out = buf.end() - count;
|
byte* out = buf.end() - count;
|
||||||
RETURN_ERR( callback( user_data, out, &count ) );
|
RETURN_ERR( callback( user_data, out, &count ) );
|
||||||
zbuf.avail_in = count;
|
zbuf.avail_in = count;
|
||||||
zbuf.next_in = out;
|
zbuf.next_in = out;
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zlib_Inflater::begin( callback_t new_callback, void* new_user_data,
|
blargg_err_t Zlib_Inflater::begin( callback_t new_callback, void* new_user_data,
|
||||||
int new_buf_size, int initial_read )
|
int new_buf_size, int initial_read )
|
||||||
{
|
{
|
||||||
callback = new_callback;
|
callback = new_callback;
|
||||||
user_data = new_user_data;
|
user_data = new_user_data;
|
||||||
|
|
||||||
end();
|
end();
|
||||||
|
|
||||||
// TODO: decide whether using different size on alloc failure is a good idea
|
// TODO: decide whether using different size on alloc failure is a good idea
|
||||||
//RETURN_ERR( buf.resize( new_buf_size ? new_buf_size : 4 * block_size ) );
|
//RETURN_ERR( buf.resize( new_buf_size ? new_buf_size : 4 * block_size ) );
|
||||||
if ( new_buf_size && buf.resize( new_buf_size ) )
|
if ( new_buf_size && buf.resize( new_buf_size ) )
|
||||||
{
|
{
|
||||||
ACK_FAILURE();
|
ACK_FAILURE();
|
||||||
new_buf_size = 0;
|
new_buf_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !new_buf_size )
|
if ( !new_buf_size )
|
||||||
{
|
{
|
||||||
RETURN_ERR( buf.resize( 4 * block_size ) );
|
RETURN_ERR( buf.resize( 4 * block_size ) );
|
||||||
initial_read = 0;
|
initial_read = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill buffer with some data, less than normal buffer size since caller might
|
// Fill buffer with some data, less than normal buffer size since caller might
|
||||||
// just be examining beginning of file.
|
// just be examining beginning of file.
|
||||||
return fill_buf( initial_read ? initial_read : block_size );
|
return fill_buf( initial_read ? initial_read : block_size );
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Zlib_Inflater::set_mode( mode_t mode, int data_offset )
|
blargg_err_t Zlib_Inflater::set_mode( mode_t mode, int data_offset )
|
||||||
{
|
{
|
||||||
zbuf.next_in += data_offset;
|
zbuf.next_in += data_offset;
|
||||||
zbuf.avail_in -= data_offset;
|
zbuf.avail_in -= data_offset;
|
||||||
|
|
||||||
if ( mode == mode_auto )
|
if ( mode == mode_auto )
|
||||||
{
|
{
|
||||||
// examine buffer for gzip header
|
// examine buffer for gzip header
|
||||||
mode = mode_copy;
|
mode = mode_copy;
|
||||||
unsigned const min_gzip_size = 2 + 8 + 8;
|
unsigned const min_gzip_size = 2 + 8 + 8;
|
||||||
if ( zbuf.avail_in >= min_gzip_size &&
|
if ( zbuf.avail_in >= min_gzip_size &&
|
||||||
zbuf.next_in [0] == 0x1F && zbuf.next_in [1] == 0x8B )
|
zbuf.next_in [0] == 0x1F && zbuf.next_in [1] == 0x8B )
|
||||||
mode = mode_ungz;
|
mode = mode_ungz;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mode != mode_copy )
|
if ( mode != mode_copy )
|
||||||
{
|
{
|
||||||
int wb = MAX_WBITS + 16; // have zlib handle gzip header
|
int wb = MAX_WBITS + 16; // have zlib handle gzip header
|
||||||
if ( mode == mode_raw_deflate )
|
if ( mode == mode_raw_deflate )
|
||||||
wb = -MAX_WBITS;
|
wb = -MAX_WBITS;
|
||||||
|
|
||||||
int zerr = inflateInit2( &zbuf, wb );
|
int zerr = inflateInit2( &zbuf, wb );
|
||||||
if ( zerr )
|
if ( zerr )
|
||||||
{
|
{
|
||||||
zbuf.next_in = NULL;
|
zbuf.next_in = NULL;
|
||||||
return get_zlib_err( zerr );
|
return get_zlib_err( zerr );
|
||||||
}
|
}
|
||||||
|
|
||||||
deflated_ = true;
|
deflated_ = true;
|
||||||
}
|
}
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Reads/inflates entire stream. All input must be in buffer, and count must be total
|
// Reads/inflates entire stream. All input must be in buffer, and count must be total
|
||||||
// of all output.
|
// of all output.
|
||||||
blargg_err_t read_all( void* out, int count );
|
blargg_err_t read_all( void* out, int count );
|
||||||
|
|
||||||
|
|
||||||
// zlib automatically applies this optimization (uses inflateFast)
|
// zlib automatically applies this optimization (uses inflateFast)
|
||||||
// TODO: remove
|
// TODO: remove
|
||||||
blargg_err_t Zlib_Inflater::read_all( void* out, int count )
|
blargg_err_t Zlib_Inflater::read_all( void* out, int count )
|
||||||
{
|
{
|
||||||
if ( deflated_ )
|
if ( deflated_ )
|
||||||
{
|
{
|
||||||
zbuf.next_out = (Bytef*) out;
|
zbuf.next_out = (Bytef*) out;
|
||||||
zbuf.avail_out = count;
|
zbuf.avail_out = count;
|
||||||
|
|
||||||
int err = inflate( &zbuf, Z_FINISH );
|
int err = inflate( &zbuf, Z_FINISH );
|
||||||
|
|
||||||
if ( zbuf.avail_out || err != Z_STREAM_END )
|
if ( zbuf.avail_out || err != Z_STREAM_END )
|
||||||
return blargg_err_file_corrupt;
|
return blargg_err_file_corrupt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( zbuf.avail_in < count )
|
if ( zbuf.avail_in < count )
|
||||||
return blargg_err_file_corrupt;
|
return blargg_err_file_corrupt;
|
||||||
|
|
||||||
memcpy( out, zbuf.next_in, count );
|
memcpy( out, zbuf.next_in, count );
|
||||||
|
|
||||||
zbuf.next_in += count;
|
zbuf.next_in += count;
|
||||||
zbuf.avail_in -= count;
|
zbuf.avail_in -= count;
|
||||||
}
|
}
|
||||||
|
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
blargg_err_t Zlib_Inflater::read( void* out, int* count_io )
|
blargg_err_t Zlib_Inflater::read( void* out, int* count_io )
|
||||||
{
|
{
|
||||||
int remain = *count_io;
|
int remain = *count_io;
|
||||||
if ( remain && zbuf.next_in )
|
if ( remain && zbuf.next_in )
|
||||||
{
|
{
|
||||||
if ( deflated_ )
|
if ( deflated_ )
|
||||||
{
|
{
|
||||||
zbuf.next_out = (Bytef*) out;
|
zbuf.next_out = (Bytef*) out;
|
||||||
zbuf.avail_out = remain;
|
zbuf.avail_out = remain;
|
||||||
|
|
||||||
while ( 1 )
|
while ( 1 )
|
||||||
{
|
{
|
||||||
uInt old_avail_in = zbuf.avail_in;
|
uInt old_avail_in = zbuf.avail_in;
|
||||||
int err = inflate( &zbuf, Z_NO_FLUSH );
|
int err = inflate( &zbuf, Z_NO_FLUSH );
|
||||||
if ( err == Z_STREAM_END )
|
if ( err == Z_STREAM_END )
|
||||||
{
|
{
|
||||||
remain = zbuf.avail_out;
|
remain = zbuf.avail_out;
|
||||||
end();
|
end();
|
||||||
break; // no more data to inflate
|
break; // no more data to inflate
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( err && (err != Z_BUF_ERROR || old_avail_in) )
|
if ( err && (err != Z_BUF_ERROR || old_avail_in) )
|
||||||
return get_zlib_err( err );
|
return get_zlib_err( err );
|
||||||
|
|
||||||
if ( !zbuf.avail_out )
|
if ( !zbuf.avail_out )
|
||||||
{
|
{
|
||||||
remain = 0;
|
remain = 0;
|
||||||
break; // requested number of bytes inflated
|
break; // requested number of bytes inflated
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( zbuf.avail_in )
|
if ( zbuf.avail_in )
|
||||||
{
|
{
|
||||||
// inflate() should never leave input if there's still space for output
|
// inflate() should never leave input if there's still space for output
|
||||||
check( false );
|
check( false );
|
||||||
return blargg_err_file_corrupt;
|
return blargg_err_file_corrupt;
|
||||||
}
|
}
|
||||||
|
|
||||||
RETURN_ERR( fill_buf( buf.size() ) );
|
RETURN_ERR( fill_buf( buf.size() ) );
|
||||||
if ( !zbuf.avail_in )
|
if ( !zbuf.avail_in )
|
||||||
return blargg_err_file_corrupt; // stream didn't end but there's no more data
|
return blargg_err_file_corrupt; // stream didn't end but there's no more data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while ( 1 )
|
while ( 1 )
|
||||||
{
|
{
|
||||||
// copy buffered data
|
// copy buffered data
|
||||||
if ( zbuf.avail_in )
|
if ( zbuf.avail_in )
|
||||||
{
|
{
|
||||||
long count = zbuf.avail_in;
|
long count = zbuf.avail_in;
|
||||||
if ( count > remain )
|
if ( count > remain )
|
||||||
count = remain;
|
count = remain;
|
||||||
memcpy( out, zbuf.next_in, count );
|
memcpy( out, zbuf.next_in, count );
|
||||||
zbuf.total_out += count;
|
zbuf.total_out += count;
|
||||||
out = (char*) out + count;
|
out = (char*) out + count;
|
||||||
remain -= count;
|
remain -= count;
|
||||||
zbuf.next_in += count;
|
zbuf.next_in += count;
|
||||||
zbuf.avail_in -= count;
|
zbuf.avail_in -= count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !zbuf.avail_in && zbuf.next_in < buf.end() )
|
if ( !zbuf.avail_in && zbuf.next_in < buf.end() )
|
||||||
{
|
{
|
||||||
end();
|
end();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read large request directly
|
// read large request directly
|
||||||
if ( remain + zbuf.total_out % block_size >= buf.size() )
|
if ( remain + zbuf.total_out % block_size >= buf.size() )
|
||||||
{
|
{
|
||||||
int count = remain;
|
int count = remain;
|
||||||
RETURN_ERR( callback( user_data, out, &count ) );
|
RETURN_ERR( callback( user_data, out, &count ) );
|
||||||
zbuf.total_out += count;
|
zbuf.total_out += count;
|
||||||
out = (char*) out + count;
|
out = (char*) out + count;
|
||||||
remain -= count;
|
remain -= count;
|
||||||
|
|
||||||
if ( remain )
|
if ( remain )
|
||||||
{
|
{
|
||||||
end();
|
end();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !remain )
|
if ( !remain )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
RETURN_ERR( fill_buf( buf.size() - zbuf.total_out % block_size ) );
|
RETURN_ERR( fill_buf( buf.size() - zbuf.total_out % block_size ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*count_io -= remain;
|
*count_io -= remain;
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,70 +1,70 @@
|
||||||
// Simplifies use of zlib for inflating data
|
// Simplifies use of zlib for inflating data
|
||||||
|
|
||||||
// File_Extractor 1.0.0
|
// File_Extractor 1.0.0
|
||||||
#ifndef ZLIB_INFLATER_H
|
#ifndef ZLIB_INFLATER_H
|
||||||
#define ZLIB_INFLATER_H
|
#define ZLIB_INFLATER_H
|
||||||
|
|
||||||
#include "blargg_common.h"
|
#include "blargg_common.h"
|
||||||
#include "Data_Reader.h"
|
#include "Data_Reader.h"
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
|
|
||||||
class Zlib_Inflater {
|
class Zlib_Inflater {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Reads at most min(*count,bytes_until_eof()) bytes into *out and set *count
|
// Reads at most min(*count,bytes_until_eof()) bytes into *out and set *count
|
||||||
// to that number, or returns error if that many can't be read.
|
// to that number, or returns error if that many can't be read.
|
||||||
typedef blargg_err_t (*callback_t)( void* user_data, void* out, int* count );
|
typedef blargg_err_t (*callback_t)( void* user_data, void* out, int* count );
|
||||||
|
|
||||||
// Begins by setting callback and filling buffer. Default buffer is 16K and
|
// Begins by setting callback and filling buffer. Default buffer is 16K and
|
||||||
// filled to 4K, or specify buf_size and initial_read for custom buffer size
|
// filled to 4K, or specify buf_size and initial_read for custom buffer size
|
||||||
// and how much to read initially.
|
// and how much to read initially.
|
||||||
blargg_err_t begin( callback_t, void* user_data,
|
blargg_err_t begin( callback_t, void* user_data,
|
||||||
int buf_size = 0, int initial_read = 0 );
|
int buf_size = 0, int initial_read = 0 );
|
||||||
|
|
||||||
// Data read into buffer by begin()
|
// Data read into buffer by begin()
|
||||||
const unsigned char* data() const { return zbuf.next_in; }
|
const unsigned char* data() const { return zbuf.next_in; }
|
||||||
int filled() const { return zbuf.avail_in; }
|
int filled() const { return zbuf.avail_in; }
|
||||||
|
|
||||||
// Begins inflation using specified mode. Using mode_auto selects between
|
// Begins inflation using specified mode. Using mode_auto selects between
|
||||||
// mode_copy and mode_ungz by examining first two bytes of buffer. Use
|
// mode_copy and mode_ungz by examining first two bytes of buffer. Use
|
||||||
// buf_offset to specify where data begins in buffer, in case there is
|
// buf_offset to specify where data begins in buffer, in case there is
|
||||||
// header data that should be skipped.
|
// header data that should be skipped.
|
||||||
enum mode_t { mode_copy, mode_ungz, mode_raw_deflate, mode_auto };
|
enum mode_t { mode_copy, mode_ungz, mode_raw_deflate, mode_auto };
|
||||||
blargg_err_t set_mode( mode_t, int buf_offset = 0 );
|
blargg_err_t set_mode( mode_t, int buf_offset = 0 );
|
||||||
|
|
||||||
// True if set_mode() has been called with mode_ungz or mode_raw_deflate
|
// True if set_mode() has been called with mode_ungz or mode_raw_deflate
|
||||||
bool deflated() const { return deflated_; }
|
bool deflated() const { return deflated_; }
|
||||||
|
|
||||||
// Reads/inflates at most *count_io bytes into *out and sets *count_io to actual
|
// Reads/inflates at most *count_io bytes into *out and sets *count_io to actual
|
||||||
// number of bytes read (less than requested if end of data was reached).
|
// number of bytes read (less than requested if end of data was reached).
|
||||||
// Buffers source data internally, even in copy mode, so input file can be
|
// Buffers source data internally, even in copy mode, so input file can be
|
||||||
// unbuffered without sacrificing performance.
|
// unbuffered without sacrificing performance.
|
||||||
blargg_err_t read( void* out, int* count_io );
|
blargg_err_t read( void* out, int* count_io );
|
||||||
|
|
||||||
// Total number of bytes read since begin()
|
// Total number of bytes read since begin()
|
||||||
int tell() const { return zbuf.total_out; }
|
int tell() const { return zbuf.total_out; }
|
||||||
|
|
||||||
// Ends inflation and frees memory
|
// Ends inflation and frees memory
|
||||||
void end();
|
void end();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// noncopyable
|
// noncopyable
|
||||||
Zlib_Inflater( const Zlib_Inflater& );
|
Zlib_Inflater( const Zlib_Inflater& );
|
||||||
Zlib_Inflater& operator = ( const Zlib_Inflater& );
|
Zlib_Inflater& operator = ( const Zlib_Inflater& );
|
||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
public:
|
public:
|
||||||
Zlib_Inflater();
|
Zlib_Inflater();
|
||||||
~Zlib_Inflater();
|
~Zlib_Inflater();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
z_stream_s zbuf;
|
z_stream_s zbuf;
|
||||||
blargg_vector<unsigned char> buf;
|
blargg_vector<unsigned char> buf;
|
||||||
bool deflated_;
|
bool deflated_;
|
||||||
callback_t callback;
|
callback_t callback;
|
||||||
void* user_data;
|
void* user_data;
|
||||||
|
|
||||||
blargg_err_t fill_buf( int count );
|
blargg_err_t fill_buf( int count );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,51 +1,51 @@
|
||||||
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
||||||
|
|
||||||
#include "blargg_common.h"
|
#include "blargg_common.h"
|
||||||
|
|
||||||
/* Copyright (C) 2008-2009 Shay Green. This module is free software; you
|
/* Copyright (C) 2008-2009 Shay Green. This module is free software; you
|
||||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||||
General Public License as published by the Free Software Foundation; either
|
General Public License as published by the Free Software Foundation; either
|
||||||
version 2.1 of the License, or (at your option) any later version. This
|
version 2.1 of the License, or (at your option) any later version. This
|
||||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||||
details. You should have received a copy of the GNU Lesser General Public
|
details. You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this module; if not, write to the Free Software Foundation,
|
License along with this module; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
#include "blargg_source.h"
|
#include "blargg_source.h"
|
||||||
|
|
||||||
void blargg_vector_::init()
|
void blargg_vector_::init()
|
||||||
{
|
{
|
||||||
begin_ = NULL;
|
begin_ = NULL;
|
||||||
size_ = 0;
|
size_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void blargg_vector_::clear()
|
void blargg_vector_::clear()
|
||||||
{
|
{
|
||||||
void* p = begin_;
|
void* p = begin_;
|
||||||
begin_ = NULL;
|
begin_ = NULL;
|
||||||
size_ = 0;
|
size_ = 0;
|
||||||
free( p );
|
free( p );
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t blargg_vector_::resize_( size_t n, size_t elem_size )
|
blargg_err_t blargg_vector_::resize_( size_t n, size_t elem_size )
|
||||||
{
|
{
|
||||||
if ( n != size_ )
|
if ( n != size_ )
|
||||||
{
|
{
|
||||||
if ( n == 0 )
|
if ( n == 0 )
|
||||||
{
|
{
|
||||||
// Simpler to handle explicitly. Realloc will handle a size of 0,
|
// Simpler to handle explicitly. Realloc will handle a size of 0,
|
||||||
// but then we have to avoid raising an error for a NULL return.
|
// but then we have to avoid raising an error for a NULL return.
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
void* p = realloc( begin_, n * elem_size );
|
void* p = realloc( begin_, n * elem_size );
|
||||||
CHECK_ALLOC( p );
|
CHECK_ALLOC( p );
|
||||||
begin_ = p;
|
begin_ = p;
|
||||||
size_ = n;
|
size_ = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,201 +1,201 @@
|
||||||
// Sets up common environment for Shay Green's libraries.
|
// Sets up common environment for Shay Green's libraries.
|
||||||
// To change configuration options, modify blargg_config.h, not this file.
|
// To change configuration options, modify blargg_config.h, not this file.
|
||||||
|
|
||||||
// File_Extractor 1.0.0
|
// File_Extractor 1.0.0
|
||||||
#ifndef BLARGG_COMMON_H
|
#ifndef BLARGG_COMMON_H
|
||||||
#define BLARGG_COMMON_H
|
#define BLARGG_COMMON_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
typedef const char* blargg_err_t; // 0 on success, otherwise error string
|
typedef const char* blargg_err_t; // 0 on success, otherwise error string
|
||||||
|
|
||||||
// Success; no error
|
// Success; no error
|
||||||
int const blargg_ok = 0;
|
int const blargg_ok = 0;
|
||||||
|
|
||||||
// BLARGG_RESTRICT: equivalent to C99's restrict, where supported
|
// BLARGG_RESTRICT: equivalent to C99's restrict, where supported
|
||||||
#if __GNUC__ >= 3 || _MSC_VER >= 1100
|
#if __GNUC__ >= 3 || _MSC_VER >= 1100
|
||||||
#define BLARGG_RESTRICT __restrict
|
#define BLARGG_RESTRICT __restrict
|
||||||
#else
|
#else
|
||||||
#define BLARGG_RESTRICT
|
#define BLARGG_RESTRICT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __cplusplus >= 199711
|
#if __cplusplus >= 199711
|
||||||
#define BLARGG_MUTABLE mutable
|
#define BLARGG_MUTABLE mutable
|
||||||
#else
|
#else
|
||||||
#define BLARGG_MUTABLE
|
#define BLARGG_MUTABLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant).
|
/* BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant).
|
||||||
I don't just use 'abcd' because that's implementation-dependent. */
|
I don't just use 'abcd' because that's implementation-dependent. */
|
||||||
#define BLARGG_4CHAR( a, b, c, d ) \
|
#define BLARGG_4CHAR( a, b, c, d ) \
|
||||||
((a&0xFF)*0x1000000 + (b&0xFF)*0x10000 + (c&0xFF)*0x100 + (d&0xFF))
|
((a&0xFF)*0x1000000 + (b&0xFF)*0x10000 + (c&0xFF)*0x100 + (d&0xFF))
|
||||||
|
|
||||||
/* BLARGG_STATIC_ASSERT( expr ): Generates compile error if expr is 0.
|
/* BLARGG_STATIC_ASSERT( expr ): Generates compile error if expr is 0.
|
||||||
Can be used at file, function, or class scope. */
|
Can be used at file, function, or class scope. */
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
// MSVC6 (_MSC_VER < 1300) __LINE__ fails when /Zl is specified
|
// MSVC6 (_MSC_VER < 1300) __LINE__ fails when /Zl is specified
|
||||||
#define BLARGG_STATIC_ASSERT( expr ) \
|
#define BLARGG_STATIC_ASSERT( expr ) \
|
||||||
void blargg_failed_( int (*arg) [2 / (int) !!(expr) - 1] )
|
void blargg_failed_( int (*arg) [2 / (int) !!(expr) - 1] )
|
||||||
#else
|
#else
|
||||||
// Others fail when declaring same function multiple times in class,
|
// Others fail when declaring same function multiple times in class,
|
||||||
// so differentiate them by line
|
// so differentiate them by line
|
||||||
#define BLARGG_STATIC_ASSERT( expr ) \
|
#define BLARGG_STATIC_ASSERT( expr ) \
|
||||||
void blargg_failed_( int (*arg) [2 / !!(expr) - 1] [__LINE__] )
|
void blargg_failed_( int (*arg) [2 / !!(expr) - 1] [__LINE__] )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Pure virtual functions cause a vtable entry to a "called pure virtual"
|
/* Pure virtual functions cause a vtable entry to a "called pure virtual"
|
||||||
error handler, requiring linkage to the C++ runtime library. This macro is
|
error handler, requiring linkage to the C++ runtime library. This macro is
|
||||||
used in place of the "= 0", and simply expands to its argument. During
|
used in place of the "= 0", and simply expands to its argument. During
|
||||||
development, it expands to "= 0", allowing detection of missing overrides. */
|
development, it expands to "= 0", allowing detection of missing overrides. */
|
||||||
#define BLARGG_PURE( def ) def
|
#define BLARGG_PURE( def ) def
|
||||||
|
|
||||||
/* My code depends on ASCII anywhere a character or string constant is
|
/* My code depends on ASCII anywhere a character or string constant is
|
||||||
compared with data read from a file, and anywhere file data is read and
|
compared with data read from a file, and anywhere file data is read and
|
||||||
treated as a string. */
|
treated as a string. */
|
||||||
#if '\n'!=0x0A || ' '!=0x20 || '0'!=0x30 || 'A'!=0x41 || 'a'!=0x61
|
#if '\n'!=0x0A || ' '!=0x20 || '0'!=0x30 || 'A'!=0x41 || 'a'!=0x61
|
||||||
#error "ASCII character set required"
|
#error "ASCII character set required"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* My code depends on int being at least 32 bits. Almost everything these days
|
/* My code depends on int being at least 32 bits. Almost everything these days
|
||||||
uses at least 32-bit ints, so it's hard to even find a system with 16-bit ints
|
uses at least 32-bit ints, so it's hard to even find a system with 16-bit ints
|
||||||
to test with. The issue can't be gotten around by using a suitable blargg_int
|
to test with. The issue can't be gotten around by using a suitable blargg_int
|
||||||
everywhere either, because int is often converted to implicitly when doing
|
everywhere either, because int is often converted to implicitly when doing
|
||||||
arithmetic on smaller types. */
|
arithmetic on smaller types. */
|
||||||
#if UINT_MAX < 0xFFFFFFFF
|
#if UINT_MAX < 0xFFFFFFFF
|
||||||
#error "int must be at least 32 bits"
|
#error "int must be at least 32 bits"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// In case compiler doesn't support these properly. Used rarely.
|
// In case compiler doesn't support these properly. Used rarely.
|
||||||
#define STATIC_CAST(T,expr) static_cast<T> (expr)
|
#define STATIC_CAST(T,expr) static_cast<T> (expr)
|
||||||
#define CONST_CAST( T,expr) const_cast<T> (expr)
|
#define CONST_CAST( T,expr) const_cast<T> (expr)
|
||||||
|
|
||||||
// User configuration can override the above macros if necessary
|
// User configuration can override the above macros if necessary
|
||||||
#include "blargg_config.h"
|
#include "blargg_config.h"
|
||||||
|
|
||||||
/* BLARGG_DEPRECATED [_TEXT] for any declarations/text to be removed in a
|
/* BLARGG_DEPRECATED [_TEXT] for any declarations/text to be removed in a
|
||||||
future version. In GCC, we can let the compiler warn. In other compilers,
|
future version. In GCC, we can let the compiler warn. In other compilers,
|
||||||
we strip it out unless BLARGG_LEGACY is true. */
|
we strip it out unless BLARGG_LEGACY is true. */
|
||||||
#if BLARGG_LEGACY
|
#if BLARGG_LEGACY
|
||||||
// Allow old client code to work without warnings
|
// Allow old client code to work without warnings
|
||||||
#define BLARGG_DEPRECATED_TEXT( text ) text
|
#define BLARGG_DEPRECATED_TEXT( text ) text
|
||||||
#define BLARGG_DEPRECATED( text ) text
|
#define BLARGG_DEPRECATED( text ) text
|
||||||
#elif __GNUC__ >= 4
|
#elif __GNUC__ >= 4
|
||||||
// In GCC, we can mark declarations and let the compiler warn
|
// In GCC, we can mark declarations and let the compiler warn
|
||||||
#define BLARGG_DEPRECATED_TEXT( text ) text
|
#define BLARGG_DEPRECATED_TEXT( text ) text
|
||||||
#define BLARGG_DEPRECATED( text ) __attribute__ ((deprecated)) text
|
#define BLARGG_DEPRECATED( text ) __attribute__ ((deprecated)) text
|
||||||
#else
|
#else
|
||||||
// By default, deprecated items are removed, to avoid use in new code
|
// By default, deprecated items are removed, to avoid use in new code
|
||||||
#define BLARGG_DEPRECATED_TEXT( text )
|
#define BLARGG_DEPRECATED_TEXT( text )
|
||||||
#define BLARGG_DEPRECATED( text )
|
#define BLARGG_DEPRECATED( text )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* BOOST::int8_t, BOOST::int32_t, etc.
|
/* BOOST::int8_t, BOOST::int32_t, etc.
|
||||||
I used BOOST since I originally was going to allow use of the boost library
|
I used BOOST since I originally was going to allow use of the boost library
|
||||||
for prividing the definitions. If I'm defining them, they must be scoped or
|
for prividing the definitions. If I'm defining them, they must be scoped or
|
||||||
else they could conflict with the standard ones at global scope. Even if
|
else they could conflict with the standard ones at global scope. Even if
|
||||||
HAVE_STDINT_H isn't defined, I can't assume the typedefs won't exist at
|
HAVE_STDINT_H isn't defined, I can't assume the typedefs won't exist at
|
||||||
global scope already. */
|
global scope already. */
|
||||||
#if defined (HAVE_STDINT_H) || \
|
#if defined (HAVE_STDINT_H) || \
|
||||||
UCHAR_MAX != 0xFF || USHRT_MAX != 0xFFFF || UINT_MAX != 0xFFFFFFFF
|
UCHAR_MAX != 0xFF || USHRT_MAX != 0xFFFF || UINT_MAX != 0xFFFFFFFF
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#define BOOST
|
#define BOOST
|
||||||
#else
|
#else
|
||||||
struct BOOST
|
struct BOOST
|
||||||
{
|
{
|
||||||
typedef signed char int8_t;
|
typedef signed char int8_t;
|
||||||
typedef unsigned char uint8_t;
|
typedef unsigned char uint8_t;
|
||||||
typedef short int16_t;
|
typedef short int16_t;
|
||||||
typedef unsigned short uint16_t;
|
typedef unsigned short uint16_t;
|
||||||
typedef int int32_t;
|
typedef int int32_t;
|
||||||
typedef unsigned int uint32_t;
|
typedef unsigned int uint32_t;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* My code is not written with exceptions in mind, so either uses new (nothrow)
|
/* My code is not written with exceptions in mind, so either uses new (nothrow)
|
||||||
OR overrides operator new in my classes. The former is best since clients
|
OR overrides operator new in my classes. The former is best since clients
|
||||||
creating objects will get standard exceptions on failure, but that causes it
|
creating objects will get standard exceptions on failure, but that causes it
|
||||||
to require the standard C++ library. So, when the client is using the C
|
to require the standard C++ library. So, when the client is using the C
|
||||||
interface, I override operator new to use malloc. */
|
interface, I override operator new to use malloc. */
|
||||||
|
|
||||||
// BLARGG_DISABLE_NOTHROW is put inside classes
|
// BLARGG_DISABLE_NOTHROW is put inside classes
|
||||||
#ifndef BLARGG_DISABLE_NOTHROW
|
#ifndef BLARGG_DISABLE_NOTHROW
|
||||||
// throw spec mandatory in ISO C++ if NULL can be returned
|
// throw spec mandatory in ISO C++ if NULL can be returned
|
||||||
#if __cplusplus >= 199711 || __GNUC__ >= 3 || _MSC_VER >= 1300
|
#if __cplusplus >= 199711 || __GNUC__ >= 3 || _MSC_VER >= 1300
|
||||||
#define BLARGG_THROWS_NOTHING throw ()
|
#define BLARGG_THROWS_NOTHING throw ()
|
||||||
#else
|
#else
|
||||||
#define BLARGG_THROWS_NOTHING
|
#define BLARGG_THROWS_NOTHING
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BLARGG_DISABLE_NOTHROW \
|
#define BLARGG_DISABLE_NOTHROW \
|
||||||
void* operator new ( size_t s ) BLARGG_THROWS_NOTHING { return malloc( s ); }\
|
void* operator new ( size_t s ) BLARGG_THROWS_NOTHING { return malloc( s ); }\
|
||||||
void operator delete( void* p ) BLARGG_THROWS_NOTHING { free( p ); }
|
void operator delete( void* p ) BLARGG_THROWS_NOTHING { free( p ); }
|
||||||
|
|
||||||
#define BLARGG_NEW new
|
#define BLARGG_NEW new
|
||||||
#else
|
#else
|
||||||
// BLARGG_NEW is used in place of new in library code
|
// BLARGG_NEW is used in place of new in library code
|
||||||
#include <new>
|
#include <new>
|
||||||
#define BLARGG_NEW new (std::nothrow)
|
#define BLARGG_NEW new (std::nothrow)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class blargg_vector_ {
|
class blargg_vector_ {
|
||||||
protected:
|
protected:
|
||||||
void* begin_;
|
void* begin_;
|
||||||
size_t size_;
|
size_t size_;
|
||||||
void init();
|
void init();
|
||||||
blargg_err_t resize_( size_t n, size_t elem_size );
|
blargg_err_t resize_( size_t n, size_t elem_size );
|
||||||
public:
|
public:
|
||||||
size_t size() const { return size_; }
|
size_t size() const { return size_; }
|
||||||
void clear();
|
void clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Very lightweight vector for POD types (no constructor/destructor)
|
// Very lightweight vector for POD types (no constructor/destructor)
|
||||||
template<class T>
|
template<class T>
|
||||||
class blargg_vector : public blargg_vector_ {
|
class blargg_vector : public blargg_vector_ {
|
||||||
union T_must_be_pod { T t; }; // fails if T is not POD
|
union T_must_be_pod { T t; }; // fails if T is not POD
|
||||||
public:
|
public:
|
||||||
blargg_vector() { init(); }
|
blargg_vector() { init(); }
|
||||||
~blargg_vector() { clear(); }
|
~blargg_vector() { clear(); }
|
||||||
|
|
||||||
blargg_err_t resize( size_t n ) { return resize_( n, sizeof (T) ); }
|
blargg_err_t resize( size_t n ) { return resize_( n, sizeof (T) ); }
|
||||||
|
|
||||||
T* begin() { return static_cast<T*> (begin_); }
|
T* begin() { return static_cast<T*> (begin_); }
|
||||||
const T* begin() const { return static_cast<T*> (begin_); }
|
const T* begin() const { return static_cast<T*> (begin_); }
|
||||||
|
|
||||||
T* end() { return static_cast<T*> (begin_) + size_; }
|
T* end() { return static_cast<T*> (begin_) + size_; }
|
||||||
const T* end() const { return static_cast<T*> (begin_) + size_; }
|
const T* end() const { return static_cast<T*> (begin_) + size_; }
|
||||||
|
|
||||||
T& operator [] ( size_t n )
|
T& operator [] ( size_t n )
|
||||||
{
|
{
|
||||||
assert( n < size_ );
|
assert( n < size_ );
|
||||||
return static_cast<T*> (begin_) [n];
|
return static_cast<T*> (begin_) [n];
|
||||||
}
|
}
|
||||||
|
|
||||||
const T& operator [] ( size_t n ) const
|
const T& operator [] ( size_t n ) const
|
||||||
{
|
{
|
||||||
assert( n < size_ );
|
assert( n < size_ );
|
||||||
return static_cast<T*> (begin_) [n];
|
return static_cast<T*> (begin_) [n];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Callback function with user data.
|
// Callback function with user data.
|
||||||
// blargg_callback<T> set_callback; // for user, this acts like...
|
// blargg_callback<T> set_callback; // for user, this acts like...
|
||||||
// void set_callback( T func, void* user_data = NULL ); // ...this
|
// void set_callback( T func, void* user_data = NULL ); // ...this
|
||||||
// To call function, do set_callback.f( .. set_callback.data ... );
|
// To call function, do set_callback.f( .. set_callback.data ... );
|
||||||
template<class T>
|
template<class T>
|
||||||
struct blargg_callback
|
struct blargg_callback
|
||||||
{
|
{
|
||||||
T f;
|
T f;
|
||||||
void* data;
|
void* data;
|
||||||
blargg_callback() { f = NULL; }
|
blargg_callback() { f = NULL; }
|
||||||
void operator () ( T callback, void* user_data = NULL ) { f = callback; data = user_data; }
|
void operator () ( T callback, void* user_data = NULL ) { f = callback; data = user_data; }
|
||||||
};
|
};
|
||||||
|
|
||||||
BLARGG_DEPRECATED( typedef signed int blargg_long; )
|
BLARGG_DEPRECATED( typedef signed int blargg_long; )
|
||||||
BLARGG_DEPRECATED( typedef unsigned int blargg_ulong; )
|
BLARGG_DEPRECATED( typedef unsigned int blargg_ulong; )
|
||||||
#if BLARGG_LEGACY
|
#if BLARGG_LEGACY
|
||||||
#define BOOST_STATIC_ASSERT BLARGG_STATIC_ASSERT
|
#define BOOST_STATIC_ASSERT BLARGG_STATIC_ASSERT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
// Library configuration. Modify this file as necessary.
|
// Library configuration. Modify this file as necessary.
|
||||||
|
|
||||||
// File_Extractor 1.0.0
|
// File_Extractor 1.0.0
|
||||||
#ifndef BLARGG_CONFIG_H
|
#ifndef BLARGG_CONFIG_H
|
||||||
#define BLARGG_CONFIG_H
|
#define BLARGG_CONFIG_H
|
||||||
|
|
||||||
// Uncomment a #define line below to have effect described.
|
// Uncomment a #define line below to have effect described.
|
||||||
|
|
||||||
// Enable RAR archive support. Doing so adds extra licensing restrictions
|
// Enable RAR archive support. Doing so adds extra licensing restrictions
|
||||||
// to this library (see unrar/readme.txt for more information).
|
// to this library (see unrar/readme.txt for more information).
|
||||||
//#define FEX_ENABLE_RAR 1
|
//#define FEX_ENABLE_RAR 1
|
||||||
|
|
||||||
// Accept file paths encoded as UTF-8. Currently only affects Windows,
|
// Accept file paths encoded as UTF-8. Currently only affects Windows,
|
||||||
// as Unix/Linux/Mac OS X already use UTF-8 paths.
|
// as Unix/Linux/Mac OS X already use UTF-8 paths.
|
||||||
//#define BLARGG_UTF8_PATHS 1
|
//#define BLARGG_UTF8_PATHS 1
|
||||||
|
|
||||||
// Enable support for as building DLL on Windows.
|
// Enable support for as building DLL on Windows.
|
||||||
//#define BLARGG_BUILD_DLL 1
|
//#define BLARGG_BUILD_DLL 1
|
||||||
|
|
||||||
// Support only the listed archive types. Remove any you don't need.
|
// Support only the listed archive types. Remove any you don't need.
|
||||||
#define FEX_TYPE_LIST \
|
#define FEX_TYPE_LIST \
|
||||||
fex_7z_type,\
|
fex_7z_type,\
|
||||||
fex_gz_type,\
|
fex_gz_type,\
|
||||||
fex_zip_type,
|
fex_zip_type,
|
||||||
|
|
||||||
// Use standard config.h if present
|
// Use standard config.h if present
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,185 +1,185 @@
|
||||||
// CPU Byte Order Utilities
|
// CPU Byte Order Utilities
|
||||||
|
|
||||||
// File_Extractor 1.0.0
|
// File_Extractor 1.0.0
|
||||||
#ifndef BLARGG_ENDIAN_H
|
#ifndef BLARGG_ENDIAN_H
|
||||||
#define BLARGG_ENDIAN_H
|
#define BLARGG_ENDIAN_H
|
||||||
|
|
||||||
#include "blargg_common.h"
|
#include "blargg_common.h"
|
||||||
|
|
||||||
// BLARGG_CPU_CISC: Defined if CPU has very few general-purpose registers (< 16)
|
// BLARGG_CPU_CISC: Defined if CPU has very few general-purpose registers (< 16)
|
||||||
#if defined (__i386__) || defined (__x86_64__) || defined (_M_IX86) || defined (_M_X64)
|
#if defined (__i386__) || defined (__x86_64__) || defined (_M_IX86) || defined (_M_X64)
|
||||||
#define BLARGG_CPU_X86 1
|
#define BLARGG_CPU_X86 1
|
||||||
#define BLARGG_CPU_CISC 1
|
#define BLARGG_CPU_CISC 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__) || \
|
#if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__) || \
|
||||||
defined (__POWERPC__) || defined (__powerc)
|
defined (__POWERPC__) || defined (__powerc)
|
||||||
#define BLARGG_CPU_POWERPC 1
|
#define BLARGG_CPU_POWERPC 1
|
||||||
#define BLARGG_CPU_RISC 1
|
#define BLARGG_CPU_RISC 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// BLARGG_BIG_ENDIAN, BLARGG_LITTLE_ENDIAN: Determined automatically, otherwise only
|
// BLARGG_BIG_ENDIAN, BLARGG_LITTLE_ENDIAN: Determined automatically, otherwise only
|
||||||
// one may be #defined to 1. Only needed if something actually depends on byte order.
|
// one may be #defined to 1. Only needed if something actually depends on byte order.
|
||||||
#if !defined (BLARGG_BIG_ENDIAN) && !defined (BLARGG_LITTLE_ENDIAN)
|
#if !defined (BLARGG_BIG_ENDIAN) && !defined (BLARGG_LITTLE_ENDIAN)
|
||||||
#ifdef __GLIBC__
|
#ifdef __GLIBC__
|
||||||
// GCC handles this for us
|
// GCC handles this for us
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||||
#define BLARGG_LITTLE_ENDIAN 1
|
#define BLARGG_LITTLE_ENDIAN 1
|
||||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||||
#define BLARGG_BIG_ENDIAN 1
|
#define BLARGG_BIG_ENDIAN 1
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if defined (LSB_FIRST) || defined (__LITTLE_ENDIAN__) || BLARGG_CPU_X86 || \
|
#if defined (LSB_FIRST) || defined (__LITTLE_ENDIAN__) || BLARGG_CPU_X86 || \
|
||||||
(defined (LITTLE_ENDIAN) && LITTLE_ENDIAN+0 != 1234)
|
(defined (LITTLE_ENDIAN) && LITTLE_ENDIAN+0 != 1234)
|
||||||
#define BLARGG_LITTLE_ENDIAN 1
|
#define BLARGG_LITTLE_ENDIAN 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (MSB_FIRST) || defined (__BIG_ENDIAN__) || defined (WORDS_BIGENDIAN) || \
|
#if defined (MSB_FIRST) || defined (__BIG_ENDIAN__) || defined (WORDS_BIGENDIAN) || \
|
||||||
defined (__sparc__) || BLARGG_CPU_POWERPC || \
|
defined (__sparc__) || BLARGG_CPU_POWERPC || \
|
||||||
(defined (BIG_ENDIAN) && BIG_ENDIAN+0 != 4321)
|
(defined (BIG_ENDIAN) && BIG_ENDIAN+0 != 4321)
|
||||||
#define BLARGG_BIG_ENDIAN 1
|
#define BLARGG_BIG_ENDIAN 1
|
||||||
#elif !defined (__mips__)
|
#elif !defined (__mips__)
|
||||||
// No endian specified; assume little-endian, since it's most common
|
// No endian specified; assume little-endian, since it's most common
|
||||||
#define BLARGG_LITTLE_ENDIAN 1
|
#define BLARGG_LITTLE_ENDIAN 1
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BLARGG_LITTLE_ENDIAN && BLARGG_BIG_ENDIAN
|
#if BLARGG_LITTLE_ENDIAN && BLARGG_BIG_ENDIAN
|
||||||
#undef BLARGG_LITTLE_ENDIAN
|
#undef BLARGG_LITTLE_ENDIAN
|
||||||
#undef BLARGG_BIG_ENDIAN
|
#undef BLARGG_BIG_ENDIAN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline void blargg_verify_byte_order()
|
inline void blargg_verify_byte_order()
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
#if BLARGG_BIG_ENDIAN
|
#if BLARGG_BIG_ENDIAN
|
||||||
volatile int i = 1;
|
volatile int i = 1;
|
||||||
assert( *(volatile char*) &i == 0 );
|
assert( *(volatile char*) &i == 0 );
|
||||||
#elif BLARGG_LITTLE_ENDIAN
|
#elif BLARGG_LITTLE_ENDIAN
|
||||||
volatile int i = 1;
|
volatile int i = 1;
|
||||||
assert( *(volatile char*) &i != 0 );
|
assert( *(volatile char*) &i != 0 );
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned get_le16( void const* p )
|
inline unsigned get_le16( void const* p )
|
||||||
{
|
{
|
||||||
return (unsigned) ((unsigned char const*) p) [1] << 8 |
|
return (unsigned) ((unsigned char const*) p) [1] << 8 |
|
||||||
(unsigned) ((unsigned char const*) p) [0];
|
(unsigned) ((unsigned char const*) p) [0];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned get_be16( void const* p )
|
inline unsigned get_be16( void const* p )
|
||||||
{
|
{
|
||||||
return (unsigned) ((unsigned char const*) p) [0] << 8 |
|
return (unsigned) ((unsigned char const*) p) [0] << 8 |
|
||||||
(unsigned) ((unsigned char const*) p) [1];
|
(unsigned) ((unsigned char const*) p) [1];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned get_le32( void const* p )
|
inline unsigned get_le32( void const* p )
|
||||||
{
|
{
|
||||||
return (unsigned) ((unsigned char const*) p) [3] << 24 |
|
return (unsigned) ((unsigned char const*) p) [3] << 24 |
|
||||||
(unsigned) ((unsigned char const*) p) [2] << 16 |
|
(unsigned) ((unsigned char const*) p) [2] << 16 |
|
||||||
(unsigned) ((unsigned char const*) p) [1] << 8 |
|
(unsigned) ((unsigned char const*) p) [1] << 8 |
|
||||||
(unsigned) ((unsigned char const*) p) [0];
|
(unsigned) ((unsigned char const*) p) [0];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned get_be32( void const* p )
|
inline unsigned get_be32( void const* p )
|
||||||
{
|
{
|
||||||
return (unsigned) ((unsigned char const*) p) [0] << 24 |
|
return (unsigned) ((unsigned char const*) p) [0] << 24 |
|
||||||
(unsigned) ((unsigned char const*) p) [1] << 16 |
|
(unsigned) ((unsigned char const*) p) [1] << 16 |
|
||||||
(unsigned) ((unsigned char const*) p) [2] << 8 |
|
(unsigned) ((unsigned char const*) p) [2] << 8 |
|
||||||
(unsigned) ((unsigned char const*) p) [3];
|
(unsigned) ((unsigned char const*) p) [3];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set_le16( void* p, unsigned n )
|
inline void set_le16( void* p, unsigned n )
|
||||||
{
|
{
|
||||||
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
|
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
|
||||||
((unsigned char*) p) [0] = (unsigned char) n;
|
((unsigned char*) p) [0] = (unsigned char) n;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set_be16( void* p, unsigned n )
|
inline void set_be16( void* p, unsigned n )
|
||||||
{
|
{
|
||||||
((unsigned char*) p) [0] = (unsigned char) (n >> 8);
|
((unsigned char*) p) [0] = (unsigned char) (n >> 8);
|
||||||
((unsigned char*) p) [1] = (unsigned char) n;
|
((unsigned char*) p) [1] = (unsigned char) n;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set_le32( void* p, unsigned n )
|
inline void set_le32( void* p, unsigned n )
|
||||||
{
|
{
|
||||||
((unsigned char*) p) [0] = (unsigned char) n;
|
((unsigned char*) p) [0] = (unsigned char) n;
|
||||||
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
|
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
|
||||||
((unsigned char*) p) [2] = (unsigned char) (n >> 16);
|
((unsigned char*) p) [2] = (unsigned char) (n >> 16);
|
||||||
((unsigned char*) p) [3] = (unsigned char) (n >> 24);
|
((unsigned char*) p) [3] = (unsigned char) (n >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set_be32( void* p, unsigned n )
|
inline void set_be32( void* p, unsigned n )
|
||||||
{
|
{
|
||||||
((unsigned char*) p) [3] = (unsigned char) n;
|
((unsigned char*) p) [3] = (unsigned char) n;
|
||||||
((unsigned char*) p) [2] = (unsigned char) (n >> 8);
|
((unsigned char*) p) [2] = (unsigned char) (n >> 8);
|
||||||
((unsigned char*) p) [1] = (unsigned char) (n >> 16);
|
((unsigned char*) p) [1] = (unsigned char) (n >> 16);
|
||||||
((unsigned char*) p) [0] = (unsigned char) (n >> 24);
|
((unsigned char*) p) [0] = (unsigned char) (n >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BLARGG_NONPORTABLE
|
#if BLARGG_NONPORTABLE
|
||||||
// Optimized implementation if byte order is known
|
// Optimized implementation if byte order is known
|
||||||
#if BLARGG_LITTLE_ENDIAN
|
#if BLARGG_LITTLE_ENDIAN
|
||||||
#define GET_LE16( addr ) (*(BOOST::uint16_t const*) (addr))
|
#define GET_LE16( addr ) (*(BOOST::uint16_t const*) (addr))
|
||||||
#define GET_LE32( addr ) (*(BOOST::uint32_t const*) (addr))
|
#define GET_LE32( addr ) (*(BOOST::uint32_t const*) (addr))
|
||||||
#define SET_LE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
|
#define SET_LE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
|
||||||
#define SET_LE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
|
#define SET_LE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
|
||||||
#elif BLARGG_BIG_ENDIAN
|
#elif BLARGG_BIG_ENDIAN
|
||||||
#define GET_BE16( addr ) (*(BOOST::uint16_t const*) (addr))
|
#define GET_BE16( addr ) (*(BOOST::uint16_t const*) (addr))
|
||||||
#define GET_BE32( addr ) (*(BOOST::uint32_t const*) (addr))
|
#define GET_BE32( addr ) (*(BOOST::uint32_t const*) (addr))
|
||||||
#define SET_BE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
|
#define SET_BE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
|
||||||
#define SET_BE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
|
#define SET_BE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
|
||||||
|
|
||||||
#if BLARGG_CPU_POWERPC
|
#if BLARGG_CPU_POWERPC
|
||||||
// PowerPC has special byte-reversed instructions
|
// PowerPC has special byte-reversed instructions
|
||||||
#if defined (__MWERKS__)
|
#if defined (__MWERKS__)
|
||||||
#define GET_LE16( addr ) (__lhbrx( addr, 0 ))
|
#define GET_LE16( addr ) (__lhbrx( addr, 0 ))
|
||||||
#define GET_LE32( addr ) (__lwbrx( addr, 0 ))
|
#define GET_LE32( addr ) (__lwbrx( addr, 0 ))
|
||||||
#define SET_LE16( addr, in ) (__sthbrx( in, addr, 0 ))
|
#define SET_LE16( addr, in ) (__sthbrx( in, addr, 0 ))
|
||||||
#define SET_LE32( addr, in ) (__stwbrx( in, addr, 0 ))
|
#define SET_LE32( addr, in ) (__stwbrx( in, addr, 0 ))
|
||||||
#elif defined (__GNUC__)
|
#elif defined (__GNUC__)
|
||||||
#define GET_LE16( addr ) ({unsigned short ppc_lhbrx_; __asm__ volatile( "lhbrx %0,0,%1" : "=r" (ppc_lhbrx_) : "r" (addr) : "memory" ); ppc_lhbrx_;})
|
#define GET_LE16( addr ) ({unsigned short ppc_lhbrx_; __asm__ volatile( "lhbrx %0,0,%1" : "=r" (ppc_lhbrx_) : "r" (addr) : "memory" ); ppc_lhbrx_;})
|
||||||
#define GET_LE32( addr ) ({unsigned short ppc_lwbrx_; __asm__ volatile( "lwbrx %0,0,%1" : "=r" (ppc_lwbrx_) : "r" (addr) : "memory" ); ppc_lwbrx_;})
|
#define GET_LE32( addr ) ({unsigned short ppc_lwbrx_; __asm__ volatile( "lwbrx %0,0,%1" : "=r" (ppc_lwbrx_) : "r" (addr) : "memory" ); ppc_lwbrx_;})
|
||||||
#define SET_LE16( addr, in ) ({__asm__ volatile( "sthbrx %0,0,%1" : : "r" (in), "r" (addr) : "memory" );})
|
#define SET_LE16( addr, in ) ({__asm__ volatile( "sthbrx %0,0,%1" : : "r" (in), "r" (addr) : "memory" );})
|
||||||
#define SET_LE32( addr, in ) ({__asm__ volatile( "stwbrx %0,0,%1" : : "r" (in), "r" (addr) : "memory" );})
|
#define SET_LE32( addr, in ) ({__asm__ volatile( "stwbrx %0,0,%1" : : "r" (in), "r" (addr) : "memory" );})
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GET_LE16
|
#ifndef GET_LE16
|
||||||
#define GET_LE16( addr ) get_le16( addr )
|
#define GET_LE16( addr ) get_le16( addr )
|
||||||
#define SET_LE16( addr, data ) set_le16( addr, data )
|
#define SET_LE16( addr, data ) set_le16( addr, data )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GET_LE32
|
#ifndef GET_LE32
|
||||||
#define GET_LE32( addr ) get_le32( addr )
|
#define GET_LE32( addr ) get_le32( addr )
|
||||||
#define SET_LE32( addr, data ) set_le32( addr, data )
|
#define SET_LE32( addr, data ) set_le32( addr, data )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GET_BE16
|
#ifndef GET_BE16
|
||||||
#define GET_BE16( addr ) get_be16( addr )
|
#define GET_BE16( addr ) get_be16( addr )
|
||||||
#define SET_BE16( addr, data ) set_be16( addr, data )
|
#define SET_BE16( addr, data ) set_be16( addr, data )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GET_BE32
|
#ifndef GET_BE32
|
||||||
#define GET_BE32( addr ) get_be32( addr )
|
#define GET_BE32( addr ) get_be32( addr )
|
||||||
#define SET_BE32( addr, data ) set_be32( addr, data )
|
#define SET_BE32( addr, data ) set_be32( addr, data )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// auto-selecting versions
|
// auto-selecting versions
|
||||||
|
|
||||||
inline void set_le( BOOST::uint16_t* p, unsigned n ) { SET_LE16( p, n ); }
|
inline void set_le( BOOST::uint16_t* p, unsigned n ) { SET_LE16( p, n ); }
|
||||||
inline void set_le( BOOST::uint32_t* p, unsigned n ) { SET_LE32( p, n ); }
|
inline void set_le( BOOST::uint32_t* p, unsigned n ) { SET_LE32( p, n ); }
|
||||||
inline void set_be( BOOST::uint16_t* p, unsigned n ) { SET_BE16( p, n ); }
|
inline void set_be( BOOST::uint16_t* p, unsigned n ) { SET_BE16( p, n ); }
|
||||||
inline void set_be( BOOST::uint32_t* p, unsigned n ) { SET_BE32( p, n ); }
|
inline void set_be( BOOST::uint32_t* p, unsigned n ) { SET_BE32( p, n ); }
|
||||||
inline unsigned get_le( BOOST::uint16_t const* p ) { return GET_LE16( p ); }
|
inline unsigned get_le( BOOST::uint16_t const* p ) { return GET_LE16( p ); }
|
||||||
inline unsigned get_le( BOOST::uint32_t const* p ) { return GET_LE32( p ); }
|
inline unsigned get_le( BOOST::uint32_t const* p ) { return GET_LE32( p ); }
|
||||||
inline unsigned get_be( BOOST::uint16_t const* p ) { return GET_BE16( p ); }
|
inline unsigned get_be( BOOST::uint16_t const* p ) { return GET_BE16( p ); }
|
||||||
inline unsigned get_be( BOOST::uint32_t const* p ) { return GET_BE32( p ); }
|
inline unsigned get_be( BOOST::uint32_t const* p ) { return GET_BE32( p ); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,113 +1,113 @@
|
||||||
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
||||||
|
|
||||||
#include "blargg_errors.h"
|
#include "blargg_errors.h"
|
||||||
|
|
||||||
/* Copyright (C) 2009 Shay Green. This module is free software; you
|
/* Copyright (C) 2009 Shay Green. This module is free software; you
|
||||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||||
General Public License as published by the Free Software Foundation; either
|
General Public License as published by the Free Software Foundation; either
|
||||||
version 2.1 of the License, or (at your option) any later version. This
|
version 2.1 of the License, or (at your option) any later version. This
|
||||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||||
details. You should have received a copy of the GNU Lesser General Public
|
details. You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this module; if not, write to the Free Software Foundation,
|
License along with this module; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
#include "blargg_source.h"
|
#include "blargg_source.h"
|
||||||
|
|
||||||
blargg_err_def_t blargg_err_generic = BLARGG_ERR_GENERIC;
|
blargg_err_def_t blargg_err_generic = BLARGG_ERR_GENERIC;
|
||||||
blargg_err_def_t blargg_err_memory = BLARGG_ERR_MEMORY;
|
blargg_err_def_t blargg_err_memory = BLARGG_ERR_MEMORY;
|
||||||
blargg_err_def_t blargg_err_caller = BLARGG_ERR_CALLER;
|
blargg_err_def_t blargg_err_caller = BLARGG_ERR_CALLER;
|
||||||
blargg_err_def_t blargg_err_internal = BLARGG_ERR_INTERNAL;
|
blargg_err_def_t blargg_err_internal = BLARGG_ERR_INTERNAL;
|
||||||
blargg_err_def_t blargg_err_limitation = BLARGG_ERR_LIMITATION;
|
blargg_err_def_t blargg_err_limitation = BLARGG_ERR_LIMITATION;
|
||||||
|
|
||||||
blargg_err_def_t blargg_err_file_missing = BLARGG_ERR_FILE_MISSING;
|
blargg_err_def_t blargg_err_file_missing = BLARGG_ERR_FILE_MISSING;
|
||||||
blargg_err_def_t blargg_err_file_read = BLARGG_ERR_FILE_READ;
|
blargg_err_def_t blargg_err_file_read = BLARGG_ERR_FILE_READ;
|
||||||
blargg_err_def_t blargg_err_file_write = BLARGG_ERR_FILE_WRITE;
|
blargg_err_def_t blargg_err_file_write = BLARGG_ERR_FILE_WRITE;
|
||||||
blargg_err_def_t blargg_err_file_io = BLARGG_ERR_FILE_IO;
|
blargg_err_def_t blargg_err_file_io = BLARGG_ERR_FILE_IO;
|
||||||
blargg_err_def_t blargg_err_file_full = BLARGG_ERR_FILE_FULL;
|
blargg_err_def_t blargg_err_file_full = BLARGG_ERR_FILE_FULL;
|
||||||
blargg_err_def_t blargg_err_file_eof = BLARGG_ERR_FILE_EOF;
|
blargg_err_def_t blargg_err_file_eof = BLARGG_ERR_FILE_EOF;
|
||||||
|
|
||||||
blargg_err_def_t blargg_err_file_type = BLARGG_ERR_FILE_TYPE;
|
blargg_err_def_t blargg_err_file_type = BLARGG_ERR_FILE_TYPE;
|
||||||
blargg_err_def_t blargg_err_file_feature = BLARGG_ERR_FILE_FEATURE;
|
blargg_err_def_t blargg_err_file_feature = BLARGG_ERR_FILE_FEATURE;
|
||||||
blargg_err_def_t blargg_err_file_corrupt = BLARGG_ERR_FILE_CORRUPT;
|
blargg_err_def_t blargg_err_file_corrupt = BLARGG_ERR_FILE_CORRUPT;
|
||||||
|
|
||||||
const char* blargg_err_str( blargg_err_t err )
|
const char* blargg_err_str( blargg_err_t err )
|
||||||
{
|
{
|
||||||
if ( !err )
|
if ( !err )
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
if ( *err == BLARGG_ERR_TYPE("")[0] )
|
if ( *err == BLARGG_ERR_TYPE("")[0] )
|
||||||
return err + 1;
|
return err + 1;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool blargg_is_err_type( blargg_err_t err, const char type [] )
|
bool blargg_is_err_type( blargg_err_t err, const char type [] )
|
||||||
{
|
{
|
||||||
if ( err )
|
if ( err )
|
||||||
{
|
{
|
||||||
// True if first strlen(type) characters of err match type
|
// True if first strlen(type) characters of err match type
|
||||||
char const* p = err;
|
char const* p = err;
|
||||||
while ( *type && *type == *p )
|
while ( *type && *type == *p )
|
||||||
{
|
{
|
||||||
type++;
|
type++;
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !*type )
|
if ( !*type )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* blargg_err_details( blargg_err_t err )
|
const char* blargg_err_details( blargg_err_t err )
|
||||||
{
|
{
|
||||||
const char* p = err;
|
const char* p = err;
|
||||||
if ( !p )
|
if ( !p )
|
||||||
{
|
{
|
||||||
p = "";
|
p = "";
|
||||||
}
|
}
|
||||||
else if ( *p == BLARGG_ERR_TYPE("")[0] )
|
else if ( *p == BLARGG_ERR_TYPE("")[0] )
|
||||||
{
|
{
|
||||||
while ( *p && *p != ';' )
|
while ( *p && *p != ';' )
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
// Skip ; and space after it
|
// Skip ; and space after it
|
||||||
if ( *p )
|
if ( *p )
|
||||||
{
|
{
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
check( *p == ' ' );
|
check( *p == ' ' );
|
||||||
if ( *p )
|
if ( *p )
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
int blargg_err_to_code( blargg_err_t err, blargg_err_to_code_t const codes [] )
|
int blargg_err_to_code( blargg_err_t err, blargg_err_to_code_t const codes [] )
|
||||||
{
|
{
|
||||||
if ( !err )
|
if ( !err )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while ( codes->str && !blargg_is_err_type( err, codes->str ) )
|
while ( codes->str && !blargg_is_err_type( err, codes->str ) )
|
||||||
codes++;
|
codes++;
|
||||||
|
|
||||||
return codes->code;
|
return codes->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t blargg_code_to_err( int code, blargg_err_to_code_t const codes [] )
|
blargg_err_t blargg_code_to_err( int code, blargg_err_to_code_t const codes [] )
|
||||||
{
|
{
|
||||||
if ( !code )
|
if ( !code )
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
|
|
||||||
while ( codes->str && codes->code != code )
|
while ( codes->str && codes->code != code )
|
||||||
codes++;
|
codes++;
|
||||||
|
|
||||||
if ( !codes->str )
|
if ( !codes->str )
|
||||||
return blargg_err_generic;
|
return blargg_err_generic;
|
||||||
|
|
||||||
return codes->str;
|
return codes->str;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,80 +1,80 @@
|
||||||
// Error strings and conversion functions
|
// Error strings and conversion functions
|
||||||
|
|
||||||
// File_Extractor 1.0.0
|
// File_Extractor 1.0.0
|
||||||
#ifndef BLARGG_ERRORS_H
|
#ifndef BLARGG_ERRORS_H
|
||||||
#define BLARGG_ERRORS_H
|
#define BLARGG_ERRORS_H
|
||||||
|
|
||||||
#ifndef BLARGG_COMMON_H
|
#ifndef BLARGG_COMMON_H
|
||||||
#include "blargg_common.h"
|
#include "blargg_common.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef const char blargg_err_def_t [];
|
typedef const char blargg_err_def_t [];
|
||||||
|
|
||||||
// Basic errors
|
// Basic errors
|
||||||
extern blargg_err_def_t blargg_err_generic;
|
extern blargg_err_def_t blargg_err_generic;
|
||||||
extern blargg_err_def_t blargg_err_memory;
|
extern blargg_err_def_t blargg_err_memory;
|
||||||
extern blargg_err_def_t blargg_err_caller;
|
extern blargg_err_def_t blargg_err_caller;
|
||||||
extern blargg_err_def_t blargg_err_internal;
|
extern blargg_err_def_t blargg_err_internal;
|
||||||
extern blargg_err_def_t blargg_err_limitation;
|
extern blargg_err_def_t blargg_err_limitation;
|
||||||
|
|
||||||
// File low-level
|
// File low-level
|
||||||
extern blargg_err_def_t blargg_err_file_missing; // not found
|
extern blargg_err_def_t blargg_err_file_missing; // not found
|
||||||
extern blargg_err_def_t blargg_err_file_read;
|
extern blargg_err_def_t blargg_err_file_read;
|
||||||
extern blargg_err_def_t blargg_err_file_write;
|
extern blargg_err_def_t blargg_err_file_write;
|
||||||
extern blargg_err_def_t blargg_err_file_io;
|
extern blargg_err_def_t blargg_err_file_io;
|
||||||
extern blargg_err_def_t blargg_err_file_full;
|
extern blargg_err_def_t blargg_err_file_full;
|
||||||
extern blargg_err_def_t blargg_err_file_eof;
|
extern blargg_err_def_t blargg_err_file_eof;
|
||||||
|
|
||||||
// File high-level
|
// File high-level
|
||||||
extern blargg_err_def_t blargg_err_file_type; // wrong file type
|
extern blargg_err_def_t blargg_err_file_type; // wrong file type
|
||||||
extern blargg_err_def_t blargg_err_file_feature;
|
extern blargg_err_def_t blargg_err_file_feature;
|
||||||
extern blargg_err_def_t blargg_err_file_corrupt;
|
extern blargg_err_def_t blargg_err_file_corrupt;
|
||||||
|
|
||||||
// C string describing error, or "" if err == NULL
|
// C string describing error, or "" if err == NULL
|
||||||
const char* blargg_err_str( blargg_err_t err );
|
const char* blargg_err_str( blargg_err_t err );
|
||||||
|
|
||||||
// True iff error is of given type, or false if err == NULL
|
// True iff error is of given type, or false if err == NULL
|
||||||
bool blargg_is_err_type( blargg_err_t, const char type [] );
|
bool blargg_is_err_type( blargg_err_t, const char type [] );
|
||||||
|
|
||||||
// Details of error without describing main cause, or "" if err == NULL
|
// Details of error without describing main cause, or "" if err == NULL
|
||||||
const char* blargg_err_details( blargg_err_t err );
|
const char* blargg_err_details( blargg_err_t err );
|
||||||
|
|
||||||
// Converts error string to integer code using mapping table. Calls blargg_is_err_type()
|
// Converts error string to integer code using mapping table. Calls blargg_is_err_type()
|
||||||
// for each str and returns code on first match. Returns 0 if err == NULL.
|
// for each str and returns code on first match. Returns 0 if err == NULL.
|
||||||
struct blargg_err_to_code_t {
|
struct blargg_err_to_code_t {
|
||||||
const char* str;
|
const char* str;
|
||||||
int code;
|
int code;
|
||||||
};
|
};
|
||||||
int blargg_err_to_code( blargg_err_t err, blargg_err_to_code_t const [] );
|
int blargg_err_to_code( blargg_err_t err, blargg_err_to_code_t const [] );
|
||||||
|
|
||||||
// Converts error code back to string. If code == 0, returns NULL. If not in table,
|
// Converts error code back to string. If code == 0, returns NULL. If not in table,
|
||||||
// returns blargg_err_generic.
|
// returns blargg_err_generic.
|
||||||
blargg_err_t blargg_code_to_err( int code, blargg_err_to_code_t const [] );
|
blargg_err_t blargg_code_to_err( int code, blargg_err_to_code_t const [] );
|
||||||
|
|
||||||
// Generates error string literal with details of cause
|
// Generates error string literal with details of cause
|
||||||
#define BLARGG_ERR( type, str ) (type "; " str)
|
#define BLARGG_ERR( type, str ) (type "; " str)
|
||||||
|
|
||||||
// Extra space to make it clear when blargg_err_str() isn't called to get
|
// Extra space to make it clear when blargg_err_str() isn't called to get
|
||||||
// printable version of error. At some point, I might prefix error strings
|
// printable version of error. At some point, I might prefix error strings
|
||||||
// with a code, to speed conversion to a code.
|
// with a code, to speed conversion to a code.
|
||||||
#define BLARGG_ERR_TYPE( str ) " " str
|
#define BLARGG_ERR_TYPE( str ) " " str
|
||||||
|
|
||||||
// Error types to pass to BLARGG_ERR macro
|
// Error types to pass to BLARGG_ERR macro
|
||||||
#define BLARGG_ERR_GENERIC BLARGG_ERR_TYPE( "operation failed" )
|
#define BLARGG_ERR_GENERIC BLARGG_ERR_TYPE( "operation failed" )
|
||||||
#define BLARGG_ERR_MEMORY BLARGG_ERR_TYPE( "out of memory" )
|
#define BLARGG_ERR_MEMORY BLARGG_ERR_TYPE( "out of memory" )
|
||||||
#define BLARGG_ERR_CALLER BLARGG_ERR_TYPE( "internal usage bug" )
|
#define BLARGG_ERR_CALLER BLARGG_ERR_TYPE( "internal usage bug" )
|
||||||
#define BLARGG_ERR_INTERNAL BLARGG_ERR_TYPE( "internal bug" )
|
#define BLARGG_ERR_INTERNAL BLARGG_ERR_TYPE( "internal bug" )
|
||||||
#define BLARGG_ERR_LIMITATION BLARGG_ERR_TYPE( "exceeded limitation" )
|
#define BLARGG_ERR_LIMITATION BLARGG_ERR_TYPE( "exceeded limitation" )
|
||||||
|
|
||||||
#define BLARGG_ERR_FILE_MISSING BLARGG_ERR_TYPE( "file not found" )
|
#define BLARGG_ERR_FILE_MISSING BLARGG_ERR_TYPE( "file not found" )
|
||||||
#define BLARGG_ERR_FILE_READ BLARGG_ERR_TYPE( "couldn't open file" )
|
#define BLARGG_ERR_FILE_READ BLARGG_ERR_TYPE( "couldn't open file" )
|
||||||
#define BLARGG_ERR_FILE_WRITE BLARGG_ERR_TYPE( "couldn't modify file" )
|
#define BLARGG_ERR_FILE_WRITE BLARGG_ERR_TYPE( "couldn't modify file" )
|
||||||
#define BLARGG_ERR_FILE_IO BLARGG_ERR_TYPE( "read/write error" )
|
#define BLARGG_ERR_FILE_IO BLARGG_ERR_TYPE( "read/write error" )
|
||||||
#define BLARGG_ERR_FILE_FULL BLARGG_ERR_TYPE( "disk full" )
|
#define BLARGG_ERR_FILE_FULL BLARGG_ERR_TYPE( "disk full" )
|
||||||
#define BLARGG_ERR_FILE_EOF BLARGG_ERR_TYPE( "truncated file" )
|
#define BLARGG_ERR_FILE_EOF BLARGG_ERR_TYPE( "truncated file" )
|
||||||
|
|
||||||
#define BLARGG_ERR_FILE_TYPE BLARGG_ERR_TYPE( "wrong file type" )
|
#define BLARGG_ERR_FILE_TYPE BLARGG_ERR_TYPE( "wrong file type" )
|
||||||
#define BLARGG_ERR_FILE_FEATURE BLARGG_ERR_TYPE( "unsupported file feature" )
|
#define BLARGG_ERR_FILE_FEATURE BLARGG_ERR_TYPE( "unsupported file feature" )
|
||||||
#define BLARGG_ERR_FILE_CORRUPT BLARGG_ERR_TYPE( "corrupt file" )
|
#define BLARGG_ERR_FILE_CORRUPT BLARGG_ERR_TYPE( "corrupt file" )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
642
fex/fex/fex.cpp
642
fex/fex/fex.cpp
|
@ -1,321 +1,321 @@
|
||||||
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
// File_Extractor 1.0.0. http://www.slack.net/~ant/
|
||||||
|
|
||||||
#include "fex.h"
|
#include "fex.h"
|
||||||
|
|
||||||
#include "File_Extractor.h"
|
#include "File_Extractor.h"
|
||||||
#include "blargg_endian.h"
|
#include "blargg_endian.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
/* Copyright (C) 2005-2009 Shay Green. This module is free software; you
|
/* Copyright (C) 2005-2009 Shay Green. This module is free software; you
|
||||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||||
General Public License as published by the Free Software Foundation; either
|
General Public License as published by the Free Software Foundation; either
|
||||||
version 2.1 of the License, or (at your option) any later version. This
|
version 2.1 of the License, or (at your option) any later version. This
|
||||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||||
details. You should have received a copy of the GNU Lesser General Public
|
details. You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this module; if not, write to the Free Software Foundation,
|
License along with this module; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
#include "blargg_source.h"
|
#include "blargg_source.h"
|
||||||
|
|
||||||
|
|
||||||
//// Types
|
//// Types
|
||||||
|
|
||||||
BLARGG_EXPORT const fex_type_t* fex_type_list( void )
|
BLARGG_EXPORT const fex_type_t* fex_type_list( void )
|
||||||
{
|
{
|
||||||
static fex_type_t const fex_type_list_ [] =
|
static fex_type_t const fex_type_list_ [] =
|
||||||
{
|
{
|
||||||
#ifdef FEX_TYPE_LIST
|
#ifdef FEX_TYPE_LIST
|
||||||
FEX_TYPE_LIST
|
FEX_TYPE_LIST
|
||||||
#else
|
#else
|
||||||
// Modify blargg_config.h to change type list, NOT this file
|
// Modify blargg_config.h to change type list, NOT this file
|
||||||
fex_7z_type,
|
fex_7z_type,
|
||||||
fex_gz_type,
|
fex_gz_type,
|
||||||
#if FEX_ENABLE_RAR
|
#if FEX_ENABLE_RAR
|
||||||
fex_rar_type,
|
fex_rar_type,
|
||||||
#endif
|
#endif
|
||||||
fex_zip_type,
|
fex_zip_type,
|
||||||
#endif
|
#endif
|
||||||
fex_bin_type,
|
fex_bin_type,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
return fex_type_list_;
|
return fex_type_list_;
|
||||||
}
|
}
|
||||||
|
|
||||||
BLARGG_EXPORT fex_err_t fex_init( void )
|
BLARGG_EXPORT fex_err_t fex_init( void )
|
||||||
{
|
{
|
||||||
static bool inited;
|
static bool inited;
|
||||||
if ( !inited )
|
if ( !inited )
|
||||||
{
|
{
|
||||||
for ( fex_type_t const* t = fex_type_list(); *t != NULL; ++t )
|
for ( fex_type_t const* t = fex_type_list(); *t != NULL; ++t )
|
||||||
{
|
{
|
||||||
if ( (*t)->init )
|
if ( (*t)->init )
|
||||||
RETURN_ERR( (*t)->init() );
|
RETURN_ERR( (*t)->init() );
|
||||||
}
|
}
|
||||||
inited = true;
|
inited = true;
|
||||||
}
|
}
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
BLARGG_EXPORT const char* fex_identify_header( void const* header )
|
BLARGG_EXPORT const char* fex_identify_header( void const* header )
|
||||||
{
|
{
|
||||||
unsigned four = get_be32( header );
|
unsigned four = get_be32( header );
|
||||||
switch ( four )
|
switch ( four )
|
||||||
{
|
{
|
||||||
case 0x52457E5E:
|
case 0x52457E5E:
|
||||||
case 0x52617221: return ".rar";
|
case 0x52617221: return ".rar";
|
||||||
|
|
||||||
case 0x377ABCAF: return ".7z";
|
case 0x377ABCAF: return ".7z";
|
||||||
|
|
||||||
case 0x504B0304:
|
case 0x504B0304:
|
||||||
case 0x504B0506: return ".zip";
|
case 0x504B0506: return ".zip";
|
||||||
|
|
||||||
case 0x53495421: return ".sit";
|
case 0x53495421: return ".sit";
|
||||||
case 0x41724301: return ".arc";
|
case 0x41724301: return ".arc";
|
||||||
case 0x4D534346: return ".cab";
|
case 0x4D534346: return ".cab";
|
||||||
case 0x5A4F4F20: return ".zoo";
|
case 0x5A4F4F20: return ".zoo";
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned three = four >> 8;
|
unsigned three = four >> 8;
|
||||||
switch ( three )
|
switch ( three )
|
||||||
{
|
{
|
||||||
case 0x425A68: return ".bz2";
|
case 0x425A68: return ".bz2";
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned two = four >> 16;
|
unsigned two = four >> 16;
|
||||||
switch ( two )
|
switch ( two )
|
||||||
{
|
{
|
||||||
case 0x1F8B: return ".gz";
|
case 0x1F8B: return ".gz";
|
||||||
case 0x60EA: return ".arj";
|
case 0x60EA: return ".arj";
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned skip_first_two = four & 0xFFFF;
|
unsigned skip_first_two = four & 0xFFFF;
|
||||||
if ( skip_first_two == 0x2D6C )
|
if ( skip_first_two == 0x2D6C )
|
||||||
return ".lha";
|
return ".lha";
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fex_has_extension_( const char str [], const char suffix [], size_t str_len )
|
static int fex_has_extension_( const char str [], const char suffix [], size_t str_len )
|
||||||
{
|
{
|
||||||
size_t suffix_len = strlen( suffix );
|
size_t suffix_len = strlen( suffix );
|
||||||
if ( str_len >= suffix_len )
|
if ( str_len >= suffix_len )
|
||||||
{
|
{
|
||||||
str += str_len - suffix_len;
|
str += str_len - suffix_len;
|
||||||
while ( *str && tolower( (unsigned char) *str ) == *suffix )
|
while ( *str && tolower( (unsigned char) *str ) == *suffix )
|
||||||
{
|
{
|
||||||
str++;
|
str++;
|
||||||
suffix++;
|
suffix++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return *suffix == 0;
|
return *suffix == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BLARGG_EXPORT int fex_has_extension( const char str [], const char suffix [] )
|
BLARGG_EXPORT int fex_has_extension( const char str [], const char suffix [] )
|
||||||
{
|
{
|
||||||
return fex_has_extension_( str, suffix, strlen( str ) );
|
return fex_has_extension_( str, suffix, strlen( str ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int is_archive_extension( const char str [] )
|
static int is_archive_extension( const char str [] )
|
||||||
{
|
{
|
||||||
static const char exts [] [6] = {
|
static const char exts [] [6] = {
|
||||||
".7z",
|
".7z",
|
||||||
".arc",
|
".arc",
|
||||||
".arj",
|
".arj",
|
||||||
".bz2",
|
".bz2",
|
||||||
".cab",
|
".cab",
|
||||||
".dmg",
|
".dmg",
|
||||||
".gz",
|
".gz",
|
||||||
".lha",
|
".lha",
|
||||||
".lz",
|
".lz",
|
||||||
".lzh",
|
".lzh",
|
||||||
".lzma",
|
".lzma",
|
||||||
".lzo",
|
".lzo",
|
||||||
".lzx",
|
".lzx",
|
||||||
".pea",
|
".pea",
|
||||||
".rar",
|
".rar",
|
||||||
".sit",
|
".sit",
|
||||||
".sitx",
|
".sitx",
|
||||||
".tgz",
|
".tgz",
|
||||||
".tlz",
|
".tlz",
|
||||||
".z",
|
".z",
|
||||||
".zip",
|
".zip",
|
||||||
".zoo",
|
".zoo",
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t str_len = strlen( str );
|
size_t str_len = strlen( str );
|
||||||
const char (*ext) [6] = exts;
|
const char (*ext) [6] = exts;
|
||||||
for ( ; **ext; ext++ )
|
for ( ; **ext; ext++ )
|
||||||
{
|
{
|
||||||
if ( fex_has_extension_( str, *ext, str_len ) )
|
if ( fex_has_extension_( str, *ext, str_len ) )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BLARGG_EXPORT fex_type_t fex_identify_extension( const char str [] )
|
BLARGG_EXPORT fex_type_t fex_identify_extension( const char str [] )
|
||||||
{
|
{
|
||||||
size_t str_len = strlen( str );
|
size_t str_len = strlen( str );
|
||||||
for ( fex_type_t const* types = fex_type_list(); *types; types++ )
|
for ( fex_type_t const* types = fex_type_list(); *types; types++ )
|
||||||
{
|
{
|
||||||
if ( fex_has_extension_( str, (*types)->extension, str_len ) )
|
if ( fex_has_extension_( str, (*types)->extension, str_len ) )
|
||||||
{
|
{
|
||||||
// Avoid treating known archive type as binary
|
// Avoid treating known archive type as binary
|
||||||
if ( *(*types)->extension || !is_archive_extension( str ) )
|
if ( *(*types)->extension || !is_archive_extension( str ) )
|
||||||
return *types;
|
return *types;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BLARGG_EXPORT fex_err_t fex_identify_file( fex_type_t* type_out, const char path [] )
|
BLARGG_EXPORT fex_err_t fex_identify_file( fex_type_t* type_out, const char path [] )
|
||||||
{
|
{
|
||||||
*type_out = NULL;
|
*type_out = NULL;
|
||||||
|
|
||||||
fex_type_t type = fex_identify_extension( path );
|
fex_type_t type = fex_identify_extension( path );
|
||||||
|
|
||||||
// Unsupported extension?
|
// Unsupported extension?
|
||||||
if ( !type )
|
if ( !type )
|
||||||
return blargg_ok; // reject
|
return blargg_ok; // reject
|
||||||
|
|
||||||
// Unknown/no extension?
|
// Unknown/no extension?
|
||||||
if ( !*(type->extension) )
|
if ( !*(type->extension) )
|
||||||
{
|
{
|
||||||
// Examine header
|
// Examine header
|
||||||
FEX_FILE_READER in;
|
FEX_FILE_READER in;
|
||||||
RETURN_ERR( in.open( path ) );
|
RETURN_ERR( in.open( path ) );
|
||||||
if ( in.remain() >= fex_identify_header_size )
|
if ( in.remain() >= fex_identify_header_size )
|
||||||
{
|
{
|
||||||
char h [fex_identify_header_size];
|
char h [fex_identify_header_size];
|
||||||
RETURN_ERR( in.read( h, sizeof h ) );
|
RETURN_ERR( in.read( h, sizeof h ) );
|
||||||
|
|
||||||
type = fex_identify_extension( fex_identify_header( h ) );
|
type = fex_identify_extension( fex_identify_header( h ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*type_out = type;
|
*type_out = type;
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
BLARGG_EXPORT fex_err_t fex_open_type( fex_t** fe_out, const char path [], fex_type_t type )
|
BLARGG_EXPORT fex_err_t fex_open_type( fex_t** fe_out, const char path [], fex_type_t type )
|
||||||
{
|
{
|
||||||
*fe_out = NULL;
|
*fe_out = NULL;
|
||||||
|
|
||||||
if ( !type )
|
if ( !type )
|
||||||
return blargg_err_file_type;
|
return blargg_err_file_type;
|
||||||
|
|
||||||
fex_t* fe = type->new_fex();
|
fex_t* fe = type->new_fex();
|
||||||
CHECK_ALLOC( fe );
|
CHECK_ALLOC( fe );
|
||||||
|
|
||||||
fex_err_t err = fe->open( path );
|
fex_err_t err = fe->open( path );
|
||||||
if ( err )
|
if ( err )
|
||||||
{
|
{
|
||||||
delete fe;
|
delete fe;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
*fe_out = fe;
|
*fe_out = fe;
|
||||||
return blargg_ok;
|
return blargg_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
BLARGG_EXPORT fex_err_t fex_open( fex_t** fe_out, const char path [] )
|
BLARGG_EXPORT fex_err_t fex_open( fex_t** fe_out, const char path [] )
|
||||||
{
|
{
|
||||||
*fe_out = NULL;
|
*fe_out = NULL;
|
||||||
|
|
||||||
fex_type_t type;
|
fex_type_t type;
|
||||||
RETURN_ERR( fex_identify_file( &type, path ) );
|
RETURN_ERR( fex_identify_file( &type, path ) );
|
||||||
|
|
||||||
return fex_open_type( fe_out, path, type );
|
return fex_open_type( fe_out, path, type );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// Wide paths
|
//// Wide paths
|
||||||
|
|
||||||
char* fex_wide_to_path( const wchar_t* wide )
|
char* fex_wide_to_path( const wchar_t* wide )
|
||||||
{
|
{
|
||||||
return blargg_to_utf8( wide );
|
return blargg_to_utf8( wide );
|
||||||
}
|
}
|
||||||
|
|
||||||
void fex_free_path( char* path )
|
void fex_free_path( char* path )
|
||||||
{
|
{
|
||||||
free( path );
|
free( path );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// Errors
|
//// Errors
|
||||||
|
|
||||||
#define ENTRY( name ) { blargg_err_##name, fex_err_##name }
|
#define ENTRY( name ) { blargg_err_##name, fex_err_##name }
|
||||||
static blargg_err_to_code_t const fex_codes [] =
|
static blargg_err_to_code_t const fex_codes [] =
|
||||||
{
|
{
|
||||||
ENTRY( generic ),
|
ENTRY( generic ),
|
||||||
ENTRY( memory ),
|
ENTRY( memory ),
|
||||||
ENTRY( caller ),
|
ENTRY( caller ),
|
||||||
ENTRY( internal ),
|
ENTRY( internal ),
|
||||||
ENTRY( limitation ),
|
ENTRY( limitation ),
|
||||||
|
|
||||||
ENTRY( file_missing ),
|
ENTRY( file_missing ),
|
||||||
ENTRY( file_read ),
|
ENTRY( file_read ),
|
||||||
ENTRY( file_io ),
|
ENTRY( file_io ),
|
||||||
ENTRY( file_eof ),
|
ENTRY( file_eof ),
|
||||||
|
|
||||||
ENTRY( file_type ),
|
ENTRY( file_type ),
|
||||||
ENTRY( file_feature ),
|
ENTRY( file_feature ),
|
||||||
ENTRY( file_corrupt ),
|
ENTRY( file_corrupt ),
|
||||||
|
|
||||||
{ 0, -1 }
|
{ 0, -1 }
|
||||||
};
|
};
|
||||||
#undef ENTRY
|
#undef ENTRY
|
||||||
|
|
||||||
static int err_code( fex_err_t err )
|
static int err_code( fex_err_t err )
|
||||||
{
|
{
|
||||||
return blargg_err_to_code( err, fex_codes );
|
return blargg_err_to_code( err, fex_codes );
|
||||||
}
|
}
|
||||||
|
|
||||||
BLARGG_EXPORT int fex_err_code( fex_err_t err )
|
BLARGG_EXPORT int fex_err_code( fex_err_t err )
|
||||||
{
|
{
|
||||||
int code = err_code( err );
|
int code = err_code( err );
|
||||||
return (code >= 0 ? code : fex_err_generic);
|
return (code >= 0 ? code : fex_err_generic);
|
||||||
}
|
}
|
||||||
|
|
||||||
BLARGG_EXPORT fex_err_t fex_code_to_err( int code )
|
BLARGG_EXPORT fex_err_t fex_code_to_err( int code )
|
||||||
{
|
{
|
||||||
return blargg_code_to_err( code, fex_codes );
|
return blargg_code_to_err( code, fex_codes );
|
||||||
}
|
}
|
||||||
|
|
||||||
BLARGG_EXPORT const char* fex_err_details( fex_err_t err )
|
BLARGG_EXPORT const char* fex_err_details( fex_err_t err )
|
||||||
{
|
{
|
||||||
// If we don't have error code assigned, return entire string
|
// If we don't have error code assigned, return entire string
|
||||||
return (err_code( err ) >= 0 ? blargg_err_details( err ) : blargg_err_str( err ));
|
return (err_code( err ) >= 0 ? blargg_err_details( err ) : blargg_err_str( err ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// Wrappers
|
//// Wrappers
|
||||||
|
|
||||||
BLARGG_EXPORT fex_err_t fex_read( fex_t* fe, void* out, int count )
|
BLARGG_EXPORT fex_err_t fex_read( fex_t* fe, void* out, int count )
|
||||||
{
|
{
|
||||||
RETURN_ERR( fe->stat() );
|
RETURN_ERR( fe->stat() );
|
||||||
return fe->reader().read( out, count );
|
return fe->reader().read( out, count );
|
||||||
}
|
}
|
||||||
|
|
||||||
BLARGG_EXPORT void fex_close ( fex_t* fe ) { delete fe; }
|
BLARGG_EXPORT void fex_close ( fex_t* fe ) { delete fe; }
|
||||||
BLARGG_EXPORT fex_type_t fex_type ( const fex_t* fe ) { return fe->type(); }
|
BLARGG_EXPORT fex_type_t fex_type ( const fex_t* fe ) { return fe->type(); }
|
||||||
BLARGG_EXPORT int fex_done ( const fex_t* fe ) { return fe->done(); }
|
BLARGG_EXPORT int fex_done ( const fex_t* fe ) { return fe->done(); }
|
||||||
BLARGG_EXPORT const char* fex_name ( const fex_t* fe ) { return fe->name(); }
|
BLARGG_EXPORT const char* fex_name ( const fex_t* fe ) { return fe->name(); }
|
||||||
BLARGG_EXPORT const wchar_t* fex_wname ( const fex_t* fe ) { return fe->wname(); }
|
BLARGG_EXPORT const wchar_t* fex_wname ( const fex_t* fe ) { return fe->wname(); }
|
||||||
BLARGG_EXPORT int fex_size ( const fex_t* fe ) { return fe->size(); }
|
BLARGG_EXPORT int fex_size ( const fex_t* fe ) { return fe->size(); }
|
||||||
BLARGG_EXPORT unsigned fex_dos_date ( const fex_t* fe ) { return fe->dos_date(); }
|
BLARGG_EXPORT unsigned fex_dos_date ( const fex_t* fe ) { return fe->dos_date(); }
|
||||||
BLARGG_EXPORT unsigned fex_crc32 ( const fex_t* fe ) { return fe->crc32(); }
|
BLARGG_EXPORT unsigned fex_crc32 ( const fex_t* fe ) { return fe->crc32(); }
|
||||||
BLARGG_EXPORT fex_err_t fex_stat ( fex_t* fe ) { return fe->stat(); }
|
BLARGG_EXPORT fex_err_t fex_stat ( fex_t* fe ) { return fe->stat(); }
|
||||||
BLARGG_EXPORT fex_err_t fex_next ( fex_t* fe ) { return fe->next(); }
|
BLARGG_EXPORT fex_err_t fex_next ( fex_t* fe ) { return fe->next(); }
|
||||||
BLARGG_EXPORT fex_err_t fex_rewind ( fex_t* fe ) { return fe->rewind(); }
|
BLARGG_EXPORT fex_err_t fex_rewind ( fex_t* fe ) { return fe->rewind(); }
|
||||||
BLARGG_EXPORT int fex_tell ( const fex_t* fe ) { return fe->tell(); }
|
BLARGG_EXPORT int fex_tell ( const fex_t* fe ) { return fe->tell(); }
|
||||||
BLARGG_EXPORT fex_pos_t fex_tell_arc ( const fex_t* fe ) { return fe->tell_arc(); }
|
BLARGG_EXPORT fex_pos_t fex_tell_arc ( const fex_t* fe ) { return fe->tell_arc(); }
|
||||||
BLARGG_EXPORT fex_err_t fex_seek_arc ( fex_t* fe, fex_pos_t pos ) { return fe->seek_arc( pos ); }
|
BLARGG_EXPORT fex_err_t fex_seek_arc ( fex_t* fe, fex_pos_t pos ) { return fe->seek_arc( pos ); }
|
||||||
BLARGG_EXPORT const char* fex_type_extension ( fex_type_t t ) { return t->extension; }
|
BLARGG_EXPORT const char* fex_type_extension ( fex_type_t t ) { return t->extension; }
|
||||||
BLARGG_EXPORT const char* fex_type_name ( fex_type_t t ) { return t->name; }
|
BLARGG_EXPORT const char* fex_type_name ( fex_type_t t ) { return t->name; }
|
||||||
BLARGG_EXPORT fex_err_t fex_data ( fex_t* fe, const void** data_out ) { return fe->data( data_out ); }
|
BLARGG_EXPORT fex_err_t fex_data ( fex_t* fe, const void** data_out ) { return fe->data( data_out ); }
|
||||||
BLARGG_EXPORT const char* fex_err_str ( fex_err_t err ) { return blargg_err_str( err ); }
|
BLARGG_EXPORT const char* fex_err_str ( fex_err_t err ) { return blargg_err_str( err ); }
|
||||||
|
|
408
fex/fex/fex.h
408
fex/fex/fex.h
|
@ -1,204 +1,204 @@
|
||||||
/** Uniform access to zip, gzip, 7-zip, and RAR compressed archives \file */
|
/** Uniform access to zip, gzip, 7-zip, and RAR compressed archives \file */
|
||||||
|
|
||||||
/* File_Extractor 1.0.0 */
|
/* File_Extractor 1.0.0 */
|
||||||
#ifndef FEX_H
|
#ifndef FEX_H
|
||||||
#define FEX_H
|
#define FEX_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/** First parameter of most functions is fex_t*, or const fex_t* if nothing is
|
/** First parameter of most functions is fex_t*, or const fex_t* if nothing is
|
||||||
changed. Once one of these functions returns an error, the archive should not
|
changed. Once one of these functions returns an error, the archive should not
|
||||||
be used any further, other than to close it. One exception is
|
be used any further, other than to close it. One exception is
|
||||||
fex_error_file_eof; the archive may still be used after this. */
|
fex_error_file_eof; the archive may still be used after this. */
|
||||||
typedef struct fex_t fex_t;
|
typedef struct fex_t fex_t;
|
||||||
|
|
||||||
/** Pointer to error, or NULL if function was successful. See error functions
|
/** Pointer to error, or NULL if function was successful. See error functions
|
||||||
below. */
|
below. */
|
||||||
#ifndef fex_err_t /* (#ifndef allows better testing of library) */
|
#ifndef fex_err_t /* (#ifndef allows better testing of library) */
|
||||||
typedef const char* fex_err_t;
|
typedef const char* fex_err_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**** File types ****/
|
/**** File types ****/
|
||||||
|
|
||||||
/** Archive file type identifier. Can also hold NULL. */
|
/** Archive file type identifier. Can also hold NULL. */
|
||||||
typedef const struct fex_type_t_* fex_type_t;
|
typedef const struct fex_type_t_* fex_type_t;
|
||||||
|
|
||||||
/** Array of supported types, with NULL at end */
|
/** Array of supported types, with NULL at end */
|
||||||
const fex_type_t* fex_type_list( void );
|
const fex_type_t* fex_type_list( void );
|
||||||
|
|
||||||
/** Name of this archive type, e.g. "ZIP archive", "file" */
|
/** Name of this archive type, e.g. "ZIP archive", "file" */
|
||||||
const char* fex_type_name( fex_type_t );
|
const char* fex_type_name( fex_type_t );
|
||||||
|
|
||||||
/** Usual file extension for type, e.g. ".zip", ".7z". For binary file type,
|
/** Usual file extension for type, e.g. ".zip", ".7z". For binary file type,
|
||||||
returns "", since it can open any file. */
|
returns "", since it can open any file. */
|
||||||
const char* fex_type_extension( fex_type_t );
|
const char* fex_type_extension( fex_type_t );
|
||||||
|
|
||||||
|
|
||||||
/**** Wide-character file paths ****/
|
/**** Wide-character file paths ****/
|
||||||
|
|
||||||
/** Converts wide-character path to form suitable for use with fex functions. */
|
/** Converts wide-character path to form suitable for use with fex functions. */
|
||||||
char* fex_wide_to_path( const wchar_t* wide );
|
char* fex_wide_to_path( const wchar_t* wide );
|
||||||
|
|
||||||
/** Frees converted path. OK to pass NULL. */
|
/** Frees converted path. OK to pass NULL. */
|
||||||
void fex_free_path( char* );
|
void fex_free_path( char* );
|
||||||
|
|
||||||
|
|
||||||
/**** Identification ****/
|
/**** Identification ****/
|
||||||
|
|
||||||
/** True if str ends in extension. If extension is "", always returns true.
|
/** True if str ends in extension. If extension is "", always returns true.
|
||||||
Converts str to lowercase before comparison, so extension should ALREADY be
|
Converts str to lowercase before comparison, so extension should ALREADY be
|
||||||
lowercase (i.e. pass ".zip", NOT ".ZIP"). */
|
lowercase (i.e. pass ".zip", NOT ".ZIP"). */
|
||||||
int fex_has_extension( const char str [], const char extension [] );
|
int fex_has_extension( const char str [], const char extension [] );
|
||||||
|
|
||||||
/** Determines type based on first fex_identify_header_size bytes of file.
|
/** Determines type based on first fex_identify_header_size bytes of file.
|
||||||
Returns usual file extension this should have (e.g. ".zip", ".gz", etc.).
|
Returns usual file extension this should have (e.g. ".zip", ".gz", etc.).
|
||||||
Returns "" if file header is not recognized. */
|
Returns "" if file header is not recognized. */
|
||||||
const char* fex_identify_header( const void* header );
|
const char* fex_identify_header( const void* header );
|
||||||
enum { fex_identify_header_size = 16 };
|
enum { fex_identify_header_size = 16 };
|
||||||
|
|
||||||
/** Determines type based on extension of a file path, or just a lone extension
|
/** Determines type based on extension of a file path, or just a lone extension
|
||||||
(must include '.', e.g. ".zip", NOT just "zip"). Returns NULL if extension is
|
(must include '.', e.g. ".zip", NOT just "zip"). Returns NULL if extension is
|
||||||
for an unsupported type (e.g. ".lzh"). */
|
for an unsupported type (e.g. ".lzh"). */
|
||||||
fex_type_t fex_identify_extension( const char path_or_extension [] );
|
fex_type_t fex_identify_extension( const char path_or_extension [] );
|
||||||
|
|
||||||
/** Determines type based on filename extension and/or file header. Sets *out
|
/** Determines type based on filename extension and/or file header. Sets *out
|
||||||
to determined type, or NULL if type is not supported. */
|
to determined type, or NULL if type is not supported. */
|
||||||
fex_err_t fex_identify_file( fex_type_t* out, const char path [] );
|
fex_err_t fex_identify_file( fex_type_t* out, const char path [] );
|
||||||
|
|
||||||
/** Type of an already-opened archive */
|
/** Type of an already-opened archive */
|
||||||
fex_type_t fex_type( const fex_t* );
|
fex_type_t fex_type( const fex_t* );
|
||||||
|
|
||||||
|
|
||||||
/**** Open/close ****/
|
/**** Open/close ****/
|
||||||
|
|
||||||
/** Initializes static tables used by library. Automatically called by
|
/** Initializes static tables used by library. Automatically called by
|
||||||
fex_open(). OK to call more than once. */
|
fex_open(). OK to call more than once. */
|
||||||
fex_err_t fex_init( void );
|
fex_err_t fex_init( void );
|
||||||
|
|
||||||
/** Opens archive and points *out at it. If error, sets *out to NULL. */
|
/** Opens archive and points *out at it. If error, sets *out to NULL. */
|
||||||
fex_err_t fex_open( fex_t** out, const char path [] );
|
fex_err_t fex_open( fex_t** out, const char path [] );
|
||||||
|
|
||||||
/** Opens archive of specified type and sets *out. Returns error if file is not
|
/** Opens archive of specified type and sets *out. Returns error if file is not
|
||||||
of that archive type. If error, sets *out to NULL. */
|
of that archive type. If error, sets *out to NULL. */
|
||||||
fex_err_t fex_open_type( fex_t** out, const char path [], fex_type_t );
|
fex_err_t fex_open_type( fex_t** out, const char path [], fex_type_t );
|
||||||
|
|
||||||
/** Closes archive and frees memory. OK to pass NULL. */
|
/** Closes archive and frees memory. OK to pass NULL. */
|
||||||
void fex_close( fex_t* );
|
void fex_close( fex_t* );
|
||||||
|
|
||||||
|
|
||||||
/**** Scanning ****/
|
/**** Scanning ****/
|
||||||
|
|
||||||
/** True if at end of archive. Must be called after fex_open() or fex_rewind(),
|
/** True if at end of archive. Must be called after fex_open() or fex_rewind(),
|
||||||
as an archive might contain no files. */
|
as an archive might contain no files. */
|
||||||
int fex_done( const fex_t* );
|
int fex_done( const fex_t* );
|
||||||
|
|
||||||
/** Goes to next file in archive. If there are no more files, fex_done() will
|
/** Goes to next file in archive. If there are no more files, fex_done() will
|
||||||
now return true. */
|
now return true. */
|
||||||
fex_err_t fex_next( fex_t* );
|
fex_err_t fex_next( fex_t* );
|
||||||
|
|
||||||
/** Goes back to first file in archive, as if it were just opened with
|
/** Goes back to first file in archive, as if it were just opened with
|
||||||
fex_open() */
|
fex_open() */
|
||||||
fex_err_t fex_rewind( fex_t* );
|
fex_err_t fex_rewind( fex_t* );
|
||||||
|
|
||||||
/** Saved position in archive. Can also store zero. */
|
/** Saved position in archive. Can also store zero. */
|
||||||
typedef int fex_pos_t;
|
typedef int fex_pos_t;
|
||||||
|
|
||||||
/** Position of current file in archive. Never returns zero. */
|
/** Position of current file in archive. Never returns zero. */
|
||||||
fex_pos_t fex_tell_arc( const fex_t* );
|
fex_pos_t fex_tell_arc( const fex_t* );
|
||||||
|
|
||||||
/** Returns to file at previously-saved position */
|
/** Returns to file at previously-saved position */
|
||||||
fex_err_t fex_seek_arc( fex_t*, fex_pos_t );
|
fex_err_t fex_seek_arc( fex_t*, fex_pos_t );
|
||||||
|
|
||||||
|
|
||||||
/**** Info ****/
|
/**** Info ****/
|
||||||
|
|
||||||
/** Name of current file */
|
/** Name of current file */
|
||||||
const char* fex_name( const fex_t* );
|
const char* fex_name( const fex_t* );
|
||||||
|
|
||||||
/** Wide-character name of current file, or NULL if unavailable */
|
/** Wide-character name of current file, or NULL if unavailable */
|
||||||
const wchar_t* fex_wname( const fex_t* );
|
const wchar_t* fex_wname( const fex_t* );
|
||||||
|
|
||||||
/** Makes further information available for file */
|
/** Makes further information available for file */
|
||||||
fex_err_t fex_stat( fex_t* );
|
fex_err_t fex_stat( fex_t* );
|
||||||
|
|
||||||
/** Size of current file. fex_stat() or fex_data() must have been called. */
|
/** Size of current file. fex_stat() or fex_data() must have been called. */
|
||||||
int fex_size( const fex_t* );
|
int fex_size( const fex_t* );
|
||||||
|
|
||||||
/** Modification date of current file (MS-DOS format), or 0 if unavailable.
|
/** Modification date of current file (MS-DOS format), or 0 if unavailable.
|
||||||
fex_stat() must have been called. */
|
fex_stat() must have been called. */
|
||||||
unsigned int fex_dos_date( const fex_t* );
|
unsigned int fex_dos_date( const fex_t* );
|
||||||
|
|
||||||
/** CRC-32 checksum of current file's contents, or 0 if unavailable. Doesn't
|
/** CRC-32 checksum of current file's contents, or 0 if unavailable. Doesn't
|
||||||
require calculation; simply gets it from file's header. fex_stat() must have
|
require calculation; simply gets it from file's header. fex_stat() must have
|
||||||
been called. */
|
been called. */
|
||||||
unsigned int fex_crc32( const fex_t* );
|
unsigned int fex_crc32( const fex_t* );
|
||||||
|
|
||||||
|
|
||||||
/**** Extraction ****/
|
/**** Extraction ****/
|
||||||
|
|
||||||
/** Reads n bytes from current file. Reading past end of file results in
|
/** Reads n bytes from current file. Reading past end of file results in
|
||||||
fex_err_file_eof. */
|
fex_err_file_eof. */
|
||||||
fex_err_t fex_read( fex_t*, void* out, int n );
|
fex_err_t fex_read( fex_t*, void* out, int n );
|
||||||
|
|
||||||
/** Number of bytes read from current file */
|
/** Number of bytes read from current file */
|
||||||
int fex_tell( const fex_t* );
|
int fex_tell( const fex_t* );
|
||||||
|
|
||||||
/** Points *out at current file's data in memory. Pointer is valid until
|
/** Points *out at current file's data in memory. Pointer is valid until
|
||||||
fex_next(), fex_rewind(), fex_seek_arc(), or fex_close() is called. Pointer
|
fex_next(), fex_rewind(), fex_seek_arc(), or fex_close() is called. Pointer
|
||||||
must NOT be freed(); library frees it automatically. If error, sets *out to
|
must NOT be freed(); library frees it automatically. If error, sets *out to
|
||||||
NULL. */
|
NULL. */
|
||||||
fex_err_t fex_data( fex_t*, const void** out );
|
fex_err_t fex_data( fex_t*, const void** out );
|
||||||
|
|
||||||
|
|
||||||
/**** Errors ****/
|
/**** Errors ****/
|
||||||
|
|
||||||
/** Error string associated with err. Returns "" if err is NULL. Returns err
|
/** Error string associated with err. Returns "" if err is NULL. Returns err
|
||||||
unchanged if it isn't a fex_err_t returned by library. */
|
unchanged if it isn't a fex_err_t returned by library. */
|
||||||
const char* fex_err_str( fex_err_t err );
|
const char* fex_err_str( fex_err_t err );
|
||||||
|
|
||||||
/** Details of error beyond main cause, or "" if none or err is NULL. Returns
|
/** Details of error beyond main cause, or "" if none or err is NULL. Returns
|
||||||
err unchanged if it isn't a fex_err_t returned by library. */
|
err unchanged if it isn't a fex_err_t returned by library. */
|
||||||
const char* fex_err_details( fex_err_t err );
|
const char* fex_err_details( fex_err_t err );
|
||||||
|
|
||||||
/** Numeric code corresponding to err. Returns fex_ok if err is NULL. Returns
|
/** Numeric code corresponding to err. Returns fex_ok if err is NULL. Returns
|
||||||
fex_err_generic if err isn't a fex_err_t returned by library. */
|
fex_err_generic if err isn't a fex_err_t returned by library. */
|
||||||
int fex_err_code( fex_err_t err );
|
int fex_err_code( fex_err_t err );
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
fex_ok = 0,/**< Successful call. Guaranteed to be zero. */
|
fex_ok = 0,/**< Successful call. Guaranteed to be zero. */
|
||||||
fex_err_generic = 0x01,/**< Error of unspecified type */
|
fex_err_generic = 0x01,/**< Error of unspecified type */
|
||||||
fex_err_memory = 0x02,/**< Out of memory */
|
fex_err_memory = 0x02,/**< Out of memory */
|
||||||
fex_err_caller = 0x03,/**< Caller called function with bad args */
|
fex_err_caller = 0x03,/**< Caller called function with bad args */
|
||||||
fex_err_internal = 0x04,/**< Internal problem, bug, etc. */
|
fex_err_internal = 0x04,/**< Internal problem, bug, etc. */
|
||||||
fex_err_limitation = 0x05,/**< Exceeded program limit */
|
fex_err_limitation = 0x05,/**< Exceeded program limit */
|
||||||
|
|
||||||
fex_err_file_missing = 0x20,/**< File not found at specified path */
|
fex_err_file_missing = 0x20,/**< File not found at specified path */
|
||||||
fex_err_file_read = 0x21,/**< Couldn't open file for reading */
|
fex_err_file_read = 0x21,/**< Couldn't open file for reading */
|
||||||
fex_err_file_io = 0x23,/**< Read/write error */
|
fex_err_file_io = 0x23,/**< Read/write error */
|
||||||
fex_err_file_eof = 0x25,/**< Tried to read past end of file */
|
fex_err_file_eof = 0x25,/**< Tried to read past end of file */
|
||||||
|
|
||||||
fex_err_file_type = 0x30,/**< File is of wrong type */
|
fex_err_file_type = 0x30,/**< File is of wrong type */
|
||||||
fex_err_file_feature = 0x32,/**< File requires unsupported feature */
|
fex_err_file_feature = 0x32,/**< File requires unsupported feature */
|
||||||
fex_err_file_corrupt = 0x33 /**< File is corrupt */
|
fex_err_file_corrupt = 0x33 /**< File is corrupt */
|
||||||
};
|
};
|
||||||
|
|
||||||
/** fex_err_t corresponding to numeric code. Note that this might not recover
|
/** fex_err_t corresponding to numeric code. Note that this might not recover
|
||||||
the original fex_err_t before it was converted to a numeric code; in
|
the original fex_err_t before it was converted to a numeric code; in
|
||||||
particular, fex_err_details(fex_code_to_err(code)) will be "" in most cases. */
|
particular, fex_err_details(fex_code_to_err(code)) will be "" in most cases. */
|
||||||
fex_err_t fex_code_to_err( int code );
|
fex_err_t fex_code_to_err( int code );
|
||||||
|
|
||||||
|
|
||||||
/* Deprecated */
|
/* Deprecated */
|
||||||
typedef fex_t File_Extractor;
|
typedef fex_t File_Extractor;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#define SVN_REV $WCREV$
|
#define SVN_REV $WCREV$
|
||||||
#define SVN_REV_STR "$WCREV$"
|
#define SVN_REV_STR "$WCREV$"
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#define SVN_REV $WCREV$
|
#define SVN_REV $WCREV$
|
||||||
#define SVN_REV_STR "$WCREV$"
|
#define SVN_REV_STR "$WCREV$"
|
||||||
|
|
184
src/System.h
184
src/System.h
|
@ -1,92 +1,92 @@
|
||||||
#ifndef SYSTEM_H
|
#ifndef SYSTEM_H
|
||||||
#define SYSTEM_H
|
#define SYSTEM_H
|
||||||
|
|
||||||
#include "common/Types.h"
|
#include "common/Types.h"
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
class SoundDriver;
|
class SoundDriver;
|
||||||
|
|
||||||
struct EmulatedSystem {
|
struct EmulatedSystem {
|
||||||
// main emulation function
|
// main emulation function
|
||||||
void (*emuMain)(int);
|
void (*emuMain)(int);
|
||||||
// reset emulator
|
// reset emulator
|
||||||
void (*emuReset)();
|
void (*emuReset)();
|
||||||
// clean up memory
|
// clean up memory
|
||||||
void (*emuCleanUp)();
|
void (*emuCleanUp)();
|
||||||
// load battery file
|
// load battery file
|
||||||
bool (*emuReadBattery)(const char *);
|
bool (*emuReadBattery)(const char *);
|
||||||
// write battery file
|
// write battery file
|
||||||
bool (*emuWriteBattery)(const char *);
|
bool (*emuWriteBattery)(const char *);
|
||||||
// load state
|
// load state
|
||||||
bool (*emuReadState)(const char *);
|
bool (*emuReadState)(const char *);
|
||||||
// save state
|
// save state
|
||||||
bool (*emuWriteState)(const char *);
|
bool (*emuWriteState)(const char *);
|
||||||
// load memory state (rewind)
|
// load memory state (rewind)
|
||||||
bool (*emuReadMemState)(char *, int);
|
bool (*emuReadMemState)(char *, int);
|
||||||
// write memory state (rewind)
|
// write memory state (rewind)
|
||||||
bool (*emuWriteMemState)(char *, int);
|
bool (*emuWriteMemState)(char *, int);
|
||||||
// write PNG file
|
// write PNG file
|
||||||
bool (*emuWritePNG)(const char *);
|
bool (*emuWritePNG)(const char *);
|
||||||
// write BMP file
|
// write BMP file
|
||||||
bool (*emuWriteBMP)(const char *);
|
bool (*emuWriteBMP)(const char *);
|
||||||
// emulator update CPSR (ARM only)
|
// emulator update CPSR (ARM only)
|
||||||
void (*emuUpdateCPSR)();
|
void (*emuUpdateCPSR)();
|
||||||
// emulator has debugger
|
// emulator has debugger
|
||||||
bool emuHasDebugger;
|
bool emuHasDebugger;
|
||||||
// clock ticks to emulate
|
// clock ticks to emulate
|
||||||
int emuCount;
|
int emuCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void log(const char *,...);
|
extern void log(const char *,...);
|
||||||
|
|
||||||
extern bool systemPauseOnFrame();
|
extern bool systemPauseOnFrame();
|
||||||
extern void systemGbPrint(u8 *,int,int,int,int);
|
extern void systemGbPrint(u8 *,int,int,int,int);
|
||||||
extern void systemScreenCapture(int);
|
extern void systemScreenCapture(int);
|
||||||
extern void systemDrawScreen();
|
extern void systemDrawScreen();
|
||||||
// updates the joystick data
|
// updates the joystick data
|
||||||
extern bool systemReadJoypads();
|
extern bool systemReadJoypads();
|
||||||
// return information about the given joystick, -1 for default joystick
|
// return information about the given joystick, -1 for default joystick
|
||||||
extern u32 systemReadJoypad(int);
|
extern u32 systemReadJoypad(int);
|
||||||
extern u32 systemGetClock();
|
extern u32 systemGetClock();
|
||||||
extern void systemMessage(int, const char *, ...);
|
extern void systemMessage(int, const char *, ...);
|
||||||
extern void systemSetTitle(const char *);
|
extern void systemSetTitle(const char *);
|
||||||
extern SoundDriver * systemSoundInit();
|
extern SoundDriver * systemSoundInit();
|
||||||
extern void systemOnWriteDataToSoundBuffer(const u16 * finalWave, int length);
|
extern void systemOnWriteDataToSoundBuffer(const u16 * finalWave, int length);
|
||||||
extern void systemOnSoundShutdown();
|
extern void systemOnSoundShutdown();
|
||||||
extern void systemScreenMessage(const char *);
|
extern void systemScreenMessage(const char *);
|
||||||
extern void systemUpdateMotionSensor();
|
extern void systemUpdateMotionSensor();
|
||||||
extern int systemGetSensorX();
|
extern int systemGetSensorX();
|
||||||
extern int systemGetSensorY();
|
extern int systemGetSensorY();
|
||||||
extern bool systemCanChangeSoundQuality();
|
extern bool systemCanChangeSoundQuality();
|
||||||
extern void systemShowSpeed(int);
|
extern void systemShowSpeed(int);
|
||||||
extern void system10Frames(int);
|
extern void system10Frames(int);
|
||||||
extern void systemFrame();
|
extern void systemFrame();
|
||||||
extern void systemGbBorderOn();
|
extern void systemGbBorderOn();
|
||||||
|
|
||||||
extern void Sm60FPS_Init();
|
extern void Sm60FPS_Init();
|
||||||
extern bool Sm60FPS_CanSkipFrame();
|
extern bool Sm60FPS_CanSkipFrame();
|
||||||
extern void Sm60FPS_Sleep();
|
extern void Sm60FPS_Sleep();
|
||||||
extern void DbgMsg(const char *msg, ...);
|
extern void DbgMsg(const char *msg, ...);
|
||||||
extern void winlog(const char *,...);
|
extern void winlog(const char *,...);
|
||||||
|
|
||||||
extern void (*dbgOutput)(const char *s, u32 addr);
|
extern void (*dbgOutput)(const char *s, u32 addr);
|
||||||
extern void (*dbgSignal)(int sig,int number);
|
extern void (*dbgSignal)(int sig,int number);
|
||||||
|
|
||||||
extern u16 systemColorMap16[0x10000];
|
extern u16 systemColorMap16[0x10000];
|
||||||
extern u32 systemColorMap32[0x10000];
|
extern u32 systemColorMap32[0x10000];
|
||||||
extern u16 systemGbPalette[24];
|
extern u16 systemGbPalette[24];
|
||||||
extern int systemRedShift;
|
extern int systemRedShift;
|
||||||
extern int systemGreenShift;
|
extern int systemGreenShift;
|
||||||
extern int systemBlueShift;
|
extern int systemBlueShift;
|
||||||
extern int systemColorDepth;
|
extern int systemColorDepth;
|
||||||
extern int systemDebug;
|
extern int systemDebug;
|
||||||
extern int systemVerbose;
|
extern int systemVerbose;
|
||||||
extern int systemFrameSkip;
|
extern int systemFrameSkip;
|
||||||
extern int systemSaveUpdateCounter;
|
extern int systemSaveUpdateCounter;
|
||||||
extern int systemSpeed;
|
extern int systemSpeed;
|
||||||
|
|
||||||
#define SYSTEM_SAVE_UPDATED 30
|
#define SYSTEM_SAVE_UPDATED 30
|
||||||
#define SYSTEM_SAVE_NOT_UPDATED 0
|
#define SYSTEM_SAVE_NOT_UPDATED 0
|
||||||
|
|
||||||
#endif // SYSTEM_H
|
#endif // SYSTEM_H
|
||||||
|
|
|
@ -1,459 +1,459 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
#include "Patch.h"
|
#include "Patch.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#if defined(__APPLE__) || defined (BSD)
|
#if defined(__APPLE__) || defined (BSD)
|
||||||
typedef off_t __off64_t; /* off_t is 64 bits on BSD. */
|
typedef off_t __off64_t; /* off_t is 64 bits on BSD. */
|
||||||
#define fseeko64 fseeko
|
#define fseeko64 fseeko
|
||||||
#define ftello64 ftello
|
#define ftello64 ftello
|
||||||
#else
|
#else
|
||||||
typedef off64_t __off64_t;
|
typedef off64_t __off64_t;
|
||||||
#endif /* __APPLE__ || BSD */
|
#endif /* __APPLE__ || BSD */
|
||||||
#endif /* __GNUC__ */
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
#define _stricmp strcasecmp
|
#define _stricmp strcasecmp
|
||||||
#endif // ! _MSC_VER
|
#endif // ! _MSC_VER
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define fseeko64 _fseeki64
|
#define fseeko64 _fseeki64
|
||||||
#define ftello64 _ftelli64
|
#define ftello64 _ftelli64
|
||||||
typedef __int64 __off64_t;
|
typedef __int64 __off64_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int readInt2(FILE *f)
|
static int readInt2(FILE *f)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int c = fgetc(f);
|
int c = fgetc(f);
|
||||||
if(c == EOF)
|
if(c == EOF)
|
||||||
return -1;
|
return -1;
|
||||||
res = c;
|
res = c;
|
||||||
c = fgetc(f);
|
c = fgetc(f);
|
||||||
if(c == EOF)
|
if(c == EOF)
|
||||||
return -1;
|
return -1;
|
||||||
return c + (res<<8);
|
return c + (res<<8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int readInt3(FILE *f)
|
static int readInt3(FILE *f)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int c = fgetc(f);
|
int c = fgetc(f);
|
||||||
if(c == EOF)
|
if(c == EOF)
|
||||||
return -1;
|
return -1;
|
||||||
res = c;
|
res = c;
|
||||||
c = fgetc(f);
|
c = fgetc(f);
|
||||||
if(c == EOF)
|
if(c == EOF)
|
||||||
return -1;
|
return -1;
|
||||||
res = c + (res<<8);
|
res = c + (res<<8);
|
||||||
c = fgetc(f);
|
c = fgetc(f);
|
||||||
if(c == EOF)
|
if(c == EOF)
|
||||||
return -1;
|
return -1;
|
||||||
return c + (res<<8);
|
return c + (res<<8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static s64 readInt4(FILE *f)
|
static s64 readInt4(FILE *f)
|
||||||
{
|
{
|
||||||
s64 tmp, res = 0;
|
s64 tmp, res = 0;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
c = fgetc(f);
|
c = fgetc(f);
|
||||||
if (c == EOF)
|
if (c == EOF)
|
||||||
return -1;
|
return -1;
|
||||||
tmp = c;
|
tmp = c;
|
||||||
res = res + (tmp << (i*8));
|
res = res + (tmp << (i*8));
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static s64 readInt8(FILE *f)
|
static s64 readInt8(FILE *f)
|
||||||
{
|
{
|
||||||
s64 tmp, res = 0;
|
s64 tmp, res = 0;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
c = fgetc(f);
|
c = fgetc(f);
|
||||||
if (c == EOF)
|
if (c == EOF)
|
||||||
return -1;
|
return -1;
|
||||||
tmp = c;
|
tmp = c;
|
||||||
res = res + (tmp << (i*8));
|
res = res + (tmp << (i*8));
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static s64 readVarPtr(FILE *f)
|
static s64 readVarPtr(FILE *f)
|
||||||
{
|
{
|
||||||
s64 offset = 0, shift = 1;
|
s64 offset = 0, shift = 1;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = fgetc(f);
|
int c = fgetc(f);
|
||||||
if (c == EOF) return 0;
|
if (c == EOF) return 0;
|
||||||
offset += (c & 0x7F) * shift;
|
offset += (c & 0x7F) * shift;
|
||||||
if (c & 0x80) break;
|
if (c & 0x80) break;
|
||||||
shift <<= 7;
|
shift <<= 7;
|
||||||
offset += shift;
|
offset += shift;
|
||||||
}
|
}
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uLong computePatchCRC(FILE *f, unsigned int size)
|
static uLong computePatchCRC(FILE *f, unsigned int size)
|
||||||
{
|
{
|
||||||
Bytef buf[4096];
|
Bytef buf[4096];
|
||||||
long readed;
|
long readed;
|
||||||
|
|
||||||
uLong crc = crc32(0L, Z_NULL, 0);
|
uLong crc = crc32(0L, Z_NULL, 0);
|
||||||
do {
|
do {
|
||||||
readed = fread(buf, 1, MIN(size, sizeof(buf)), f);
|
readed = fread(buf, 1, MIN(size, sizeof(buf)), f);
|
||||||
crc = crc32(crc, buf, readed);
|
crc = crc32(crc, buf, readed);
|
||||||
size -= readed;
|
size -= readed;
|
||||||
} while (readed > 0);
|
} while (readed > 0);
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool patchApplyIPS(const char *patchname, u8 **r, int *s)
|
static bool patchApplyIPS(const char *patchname, u8 **r, int *s)
|
||||||
{
|
{
|
||||||
// from the IPS spec at http://zerosoft.zophar.net/ips.htm
|
// from the IPS spec at http://zerosoft.zophar.net/ips.htm
|
||||||
FILE *f = fopen(patchname, "rb");
|
FILE *f = fopen(patchname, "rb");
|
||||||
if(!f)
|
if(!f)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
u8 *rom = *r;
|
u8 *rom = *r;
|
||||||
int size = *s;
|
int size = *s;
|
||||||
if(fgetc(f) == 'P' &&
|
if(fgetc(f) == 'P' &&
|
||||||
fgetc(f) == 'A' &&
|
fgetc(f) == 'A' &&
|
||||||
fgetc(f) == 'T' &&
|
fgetc(f) == 'T' &&
|
||||||
fgetc(f) == 'C' &&
|
fgetc(f) == 'C' &&
|
||||||
fgetc(f) == 'H') {
|
fgetc(f) == 'H') {
|
||||||
int b;
|
int b;
|
||||||
int offset;
|
int offset;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
// read offset
|
// read offset
|
||||||
offset = readInt3(f);
|
offset = readInt3(f);
|
||||||
// if offset == EOF, end of patch
|
// if offset == EOF, end of patch
|
||||||
if(offset == 0x454f46 || offset == -1)
|
if(offset == 0x454f46 || offset == -1)
|
||||||
break;
|
break;
|
||||||
// read length
|
// read length
|
||||||
len = readInt2(f);
|
len = readInt2(f);
|
||||||
if(!len) {
|
if(!len) {
|
||||||
// len == 0, RLE block
|
// len == 0, RLE block
|
||||||
len = readInt2(f);
|
len = readInt2(f);
|
||||||
// byte to fill
|
// byte to fill
|
||||||
int c = fgetc(f);
|
int c = fgetc(f);
|
||||||
if(c == -1)
|
if(c == -1)
|
||||||
break;
|
break;
|
||||||
b = (u8)c;
|
b = (u8)c;
|
||||||
} else
|
} else
|
||||||
b= -1;
|
b= -1;
|
||||||
// check if we need to reallocate our ROM
|
// check if we need to reallocate our ROM
|
||||||
if((offset + len) >= size) {
|
if((offset + len) >= size) {
|
||||||
size *= 2;
|
size *= 2;
|
||||||
rom = (u8 *)realloc(rom, size);
|
rom = (u8 *)realloc(rom, size);
|
||||||
*r = rom;
|
*r = rom;
|
||||||
*s = size;
|
*s = size;
|
||||||
}
|
}
|
||||||
if(b == -1) {
|
if(b == -1) {
|
||||||
// normal block, just read the data
|
// normal block, just read the data
|
||||||
if(fread(&rom[offset], 1, len, f) != (size_t)len)
|
if(fread(&rom[offset], 1, len, f) != (size_t)len)
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// fill the region with the given byte
|
// fill the region with the given byte
|
||||||
while(len--) {
|
while(len--) {
|
||||||
rom[offset++] = b;
|
rom[offset++] = b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// close the file
|
// close the file
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool patchApplyUPS(const char *patchname, u8 **rom, int *size)
|
static bool patchApplyUPS(const char *patchname, u8 **rom, int *size)
|
||||||
{
|
{
|
||||||
s64 srcCRC, dstCRC, patchCRC;
|
s64 srcCRC, dstCRC, patchCRC;
|
||||||
|
|
||||||
FILE *f = fopen(patchname, "rb");
|
FILE *f = fopen(patchname, "rb");
|
||||||
if (!f)
|
if (!f)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fseeko64(f, 0, SEEK_END);
|
fseeko64(f, 0, SEEK_END);
|
||||||
__off64_t patchSize = ftello64(f);
|
__off64_t patchSize = ftello64(f);
|
||||||
if (patchSize < 20) {
|
if (patchSize < 20) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fseeko64(f, 0, SEEK_SET);
|
fseeko64(f, 0, SEEK_SET);
|
||||||
if(fgetc(f) != 'U' || fgetc(f) != 'P' || fgetc(f) != 'S' || fgetc(f) != '1') {
|
if(fgetc(f) != 'U' || fgetc(f) != 'P' || fgetc(f) != 'S' || fgetc(f) != '1') {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fseeko64(f, -12, SEEK_END);
|
fseeko64(f, -12, SEEK_END);
|
||||||
srcCRC = readInt4(f);
|
srcCRC = readInt4(f);
|
||||||
dstCRC = readInt4(f);
|
dstCRC = readInt4(f);
|
||||||
patchCRC = readInt4(f);
|
patchCRC = readInt4(f);
|
||||||
if (srcCRC == -1 || dstCRC == -1 || patchCRC == -1) {
|
if (srcCRC == -1 || dstCRC == -1 || patchCRC == -1) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fseeko64(f, 0, SEEK_SET);
|
fseeko64(f, 0, SEEK_SET);
|
||||||
u32 crc = computePatchCRC(f, patchSize-4);
|
u32 crc = computePatchCRC(f, patchSize-4);
|
||||||
|
|
||||||
if (crc != patchCRC) {
|
if (crc != patchCRC) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
crc = crc32(0L, Z_NULL, 0);
|
crc = crc32(0L, Z_NULL, 0);
|
||||||
crc = crc32(crc, *rom, *size);
|
crc = crc32(crc, *rom, *size);
|
||||||
|
|
||||||
fseeko64(f, 4, SEEK_SET);
|
fseeko64(f, 4, SEEK_SET);
|
||||||
s64 dataSize;
|
s64 dataSize;
|
||||||
s64 srcSize = readVarPtr(f);
|
s64 srcSize = readVarPtr(f);
|
||||||
s64 dstSize = readVarPtr(f);
|
s64 dstSize = readVarPtr(f);
|
||||||
|
|
||||||
if (crc == srcCRC) {
|
if (crc == srcCRC) {
|
||||||
if (srcSize != *size) {
|
if (srcSize != *size) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
dataSize = dstSize;
|
dataSize = dstSize;
|
||||||
} else if (crc == dstCRC) {
|
} else if (crc == dstCRC) {
|
||||||
if (dstSize != *size) {
|
if (dstSize != *size) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
dataSize = srcSize;
|
dataSize = srcSize;
|
||||||
} else {
|
} else {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (dataSize > *size) {
|
if (dataSize > *size) {
|
||||||
*rom = (u8*)realloc(*rom, dataSize);
|
*rom = (u8*)realloc(*rom, dataSize);
|
||||||
memset(*rom + *size, 0, dataSize - *size);
|
memset(*rom + *size, 0, dataSize - *size);
|
||||||
*size = dataSize;
|
*size = dataSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 relative = 0;
|
s64 relative = 0;
|
||||||
u8 *mem;
|
u8 *mem;
|
||||||
while(ftello64(f) < patchSize - 12) {
|
while(ftello64(f) < patchSize - 12) {
|
||||||
relative += readVarPtr(f);
|
relative += readVarPtr(f);
|
||||||
if (relative > dataSize) continue;
|
if (relative > dataSize) continue;
|
||||||
mem = *rom + relative;
|
mem = *rom + relative;
|
||||||
for(s64 i = relative; i < dataSize; i++) {
|
for(s64 i = relative; i < dataSize; i++) {
|
||||||
int x = fgetc(f);
|
int x = fgetc(f);
|
||||||
relative++;
|
relative++;
|
||||||
if (!x) break;
|
if (!x) break;
|
||||||
if (i < dataSize) {
|
if (i < dataSize) {
|
||||||
*mem++ ^= x;
|
*mem++ ^= x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ppfVersion(FILE *f)
|
static int ppfVersion(FILE *f)
|
||||||
{
|
{
|
||||||
fseeko64(f, 0, SEEK_SET);
|
fseeko64(f, 0, SEEK_SET);
|
||||||
if (fgetc(f) != 'P' || fgetc(f) != 'P' || fgetc(f) != 'F')
|
if (fgetc(f) != 'P' || fgetc(f) != 'P' || fgetc(f) != 'F')
|
||||||
return 0;
|
return 0;
|
||||||
switch(fgetc(f)){
|
switch(fgetc(f)){
|
||||||
case '1': return 1;
|
case '1': return 1;
|
||||||
case '2': return 2;
|
case '2': return 2;
|
||||||
case '3': return 3;
|
case '3': return 3;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ppfFileIdLen(FILE *f, int version)
|
static int ppfFileIdLen(FILE *f, int version)
|
||||||
{
|
{
|
||||||
if (version == 2) {
|
if (version == 2) {
|
||||||
fseeko64(f, -8, SEEK_END);
|
fseeko64(f, -8, SEEK_END);
|
||||||
} else {
|
} else {
|
||||||
fseeko64(f, -6, SEEK_END);
|
fseeko64(f, -6, SEEK_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fgetc(f) != '.' || fgetc(f) != 'D' || fgetc(f) != 'I' || fgetc(f) != 'Z')
|
if (fgetc(f) != '.' || fgetc(f) != 'D' || fgetc(f) != 'I' || fgetc(f) != 'Z')
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return (version == 2) ? readInt4(f) : readInt2(f);
|
return (version == 2) ? readInt4(f) : readInt2(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool patchApplyPPF1(FILE *f, u8 **rom, int *size)
|
static bool patchApplyPPF1(FILE *f, u8 **rom, int *size)
|
||||||
{
|
{
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
int count = ftell(f);
|
int count = ftell(f);
|
||||||
if (count < 56)
|
if (count < 56)
|
||||||
return false;
|
return false;
|
||||||
count -= 56;
|
count -= 56;
|
||||||
|
|
||||||
fseek(f, 56, SEEK_SET);
|
fseek(f, 56, SEEK_SET);
|
||||||
|
|
||||||
u8 *mem = *rom;
|
u8 *mem = *rom;
|
||||||
|
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
int offset = readInt4(f);
|
int offset = readInt4(f);
|
||||||
if (offset == -1)
|
if (offset == -1)
|
||||||
break;
|
break;
|
||||||
int len = fgetc(f);
|
int len = fgetc(f);
|
||||||
if (len == EOF)
|
if (len == EOF)
|
||||||
break;
|
break;
|
||||||
if (offset+len > *size)
|
if (offset+len > *size)
|
||||||
break;
|
break;
|
||||||
if (fread(&mem[offset], 1, len, f) != (size_t)len)
|
if (fread(&mem[offset], 1, len, f) != (size_t)len)
|
||||||
break;
|
break;
|
||||||
count -= 4 + 1 + len;
|
count -= 4 + 1 + len;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (count == 0);
|
return (count == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool patchApplyPPF2(FILE *f, u8 **rom, int *size)
|
static bool patchApplyPPF2(FILE *f, u8 **rom, int *size)
|
||||||
{
|
{
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
int count = ftell(f);
|
int count = ftell(f);
|
||||||
if (count < 56+4+1024)
|
if (count < 56+4+1024)
|
||||||
return false;
|
return false;
|
||||||
count -= 56+4+1024;
|
count -= 56+4+1024;
|
||||||
|
|
||||||
fseek(f, 56, SEEK_SET);
|
fseek(f, 56, SEEK_SET);
|
||||||
|
|
||||||
int datalen = readInt4(f);
|
int datalen = readInt4(f);
|
||||||
if (datalen != *size)
|
if (datalen != *size)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
u8 *mem = *rom;
|
u8 *mem = *rom;
|
||||||
|
|
||||||
u8 block[1024];
|
u8 block[1024];
|
||||||
fread(&block, 1, 1024, f);
|
fread(&block, 1, 1024, f);
|
||||||
if (memcmp(&mem[0x9320], &block, 1024) != 0)
|
if (memcmp(&mem[0x9320], &block, 1024) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int idlen = ppfFileIdLen(f, 2);
|
int idlen = ppfFileIdLen(f, 2);
|
||||||
if (idlen > 0)
|
if (idlen > 0)
|
||||||
count -= 16 + 16 + idlen;
|
count -= 16 + 16 + idlen;
|
||||||
|
|
||||||
fseek(f, 56+4+1024, SEEK_SET);
|
fseek(f, 56+4+1024, SEEK_SET);
|
||||||
|
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
int offset = readInt4(f);
|
int offset = readInt4(f);
|
||||||
if (offset == -1)
|
if (offset == -1)
|
||||||
break;
|
break;
|
||||||
int len = fgetc(f);
|
int len = fgetc(f);
|
||||||
if (len == EOF)
|
if (len == EOF)
|
||||||
break;
|
break;
|
||||||
if (offset+len > *size)
|
if (offset+len > *size)
|
||||||
break;
|
break;
|
||||||
if (fread(&mem[offset], 1, len, f) != (size_t)len)
|
if (fread(&mem[offset], 1, len, f) != (size_t)len)
|
||||||
break;
|
break;
|
||||||
count -= 4 + 1 + len;
|
count -= 4 + 1 + len;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (count == 0);
|
return (count == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool patchApplyPPF3(FILE *f, u8 **rom, int *size)
|
static bool patchApplyPPF3(FILE *f, u8 **rom, int *size)
|
||||||
{
|
{
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
int count = ftell(f);
|
int count = ftell(f);
|
||||||
if (count < 56+4+1024)
|
if (count < 56+4+1024)
|
||||||
return false;
|
return false;
|
||||||
count -= 56+4;
|
count -= 56+4;
|
||||||
|
|
||||||
fseek(f, 56, SEEK_SET);
|
fseek(f, 56, SEEK_SET);
|
||||||
|
|
||||||
int imagetype = fgetc(f);
|
int imagetype = fgetc(f);
|
||||||
int blockcheck = fgetc(f);
|
int blockcheck = fgetc(f);
|
||||||
int undo = fgetc(f);
|
int undo = fgetc(f);
|
||||||
fgetc(f);
|
fgetc(f);
|
||||||
|
|
||||||
u8 *mem = *rom;
|
u8 *mem = *rom;
|
||||||
|
|
||||||
if (blockcheck) {
|
if (blockcheck) {
|
||||||
u8 block[1024];
|
u8 block[1024];
|
||||||
fread(&block, 1, 1024, f);
|
fread(&block, 1, 1024, f);
|
||||||
if (memcmp(&mem[(imagetype == 0) ? 0x9320 : 0x80A0], &block, 1024) != 0)
|
if (memcmp(&mem[(imagetype == 0) ? 0x9320 : 0x80A0], &block, 1024) != 0)
|
||||||
return false;
|
return false;
|
||||||
count -= 1024;
|
count -= 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
int idlen = ppfFileIdLen(f, 2);
|
int idlen = ppfFileIdLen(f, 2);
|
||||||
if (idlen > 0)
|
if (idlen > 0)
|
||||||
count -= 16 + 16 + idlen;
|
count -= 16 + 16 + idlen;
|
||||||
|
|
||||||
fseek(f, 56+4+(blockcheck ? 1024 : 0), SEEK_SET);
|
fseek(f, 56+4+(blockcheck ? 1024 : 0), SEEK_SET);
|
||||||
|
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
__off64_t offset = readInt8(f);
|
__off64_t offset = readInt8(f);
|
||||||
if (offset == -1)
|
if (offset == -1)
|
||||||
break;
|
break;
|
||||||
int len = fgetc(f);
|
int len = fgetc(f);
|
||||||
if (len == EOF)
|
if (len == EOF)
|
||||||
break;
|
break;
|
||||||
if (offset+len > *size)
|
if (offset+len > *size)
|
||||||
break;
|
break;
|
||||||
if (fread(&mem[offset], 1, len, f) != (size_t)len)
|
if (fread(&mem[offset], 1, len, f) != (size_t)len)
|
||||||
break;
|
break;
|
||||||
if (undo) fseeko64(f, len, SEEK_CUR);
|
if (undo) fseeko64(f, len, SEEK_CUR);
|
||||||
count -= 8 + 1 + len;
|
count -= 8 + 1 + len;
|
||||||
if (undo) count -= len;
|
if (undo) count -= len;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (count == 0);
|
return (count == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool patchApplyPPF(const char *patchname, u8 **rom, int *size)
|
static bool patchApplyPPF(const char *patchname, u8 **rom, int *size)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(patchname, "rb");
|
FILE *f = fopen(patchname, "rb");
|
||||||
if (!f)
|
if (!f)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool res = false;
|
bool res = false;
|
||||||
|
|
||||||
int version = ppfVersion(f);
|
int version = ppfVersion(f);
|
||||||
switch (version) {
|
switch (version) {
|
||||||
case 1: res = patchApplyPPF1(f, rom, size); break;
|
case 1: res = patchApplyPPF1(f, rom, size); break;
|
||||||
case 2: res = patchApplyPPF2(f, rom, size); break;
|
case 2: res = patchApplyPPF2(f, rom, size); break;
|
||||||
case 3: res = patchApplyPPF3(f, rom, size); break;
|
case 3: res = patchApplyPPF3(f, rom, size); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool applyPatch(const char *patchname, u8 **rom, int *size)
|
bool applyPatch(const char *patchname, u8 **rom, int *size)
|
||||||
{
|
{
|
||||||
if (strlen(patchname) < 5)
|
if (strlen(patchname) < 5)
|
||||||
return false;
|
return false;
|
||||||
const char * p = strrchr(patchname, '.');
|
const char * p = strrchr(patchname, '.');
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return false;
|
return false;
|
||||||
if (_stricmp(p, ".ips") == 0)
|
if (_stricmp(p, ".ips") == 0)
|
||||||
return patchApplyIPS(patchname, rom, size);
|
return patchApplyIPS(patchname, rom, size);
|
||||||
if (_stricmp(p, ".ups") == 0)
|
if (_stricmp(p, ".ups") == 0)
|
||||||
return patchApplyUPS(patchname, rom, size);
|
return patchApplyUPS(patchname, rom, size);
|
||||||
if (_stricmp(p, ".ppf") == 0)
|
if (_stricmp(p, ".ppf") == 0)
|
||||||
return patchApplyPPF(patchname, rom, size);
|
return patchApplyPPF(patchname, rom, size);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#ifndef PATCH_H
|
#ifndef PATCH_H
|
||||||
#define PATCH_H
|
#define PATCH_H
|
||||||
|
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
bool applyPatch(const char *patchname, u8 **rom, int *size);
|
bool applyPatch(const char *patchname, u8 **rom, int *size);
|
||||||
|
|
||||||
#endif // PATCH_H
|
#endif // PATCH_H
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
* Adapted from original gzio.c from zlib library by Forgotten
|
* Adapted from original gzio.c from zlib library by Forgotten
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* @(#) $Id: memgzio.c,v 1.5 2006/06/06 21:04:20 spacy51 Exp $ */
|
/* @(#) $Id$ */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
10934
src/gb/GB.cpp
10934
src/gb/GB.cpp
File diff suppressed because it is too large
Load Diff
3406
src/gb/gbMemory.cpp
3406
src/gb/gbMemory.cpp
File diff suppressed because it is too large
Load Diff
8132
src/gba/GBA.cpp
8132
src/gba/GBA.cpp
File diff suppressed because it is too large
Load Diff
|
@ -1,38 +1,38 @@
|
||||||
#include "GBASockClient.h"
|
#include "GBASockClient.h"
|
||||||
|
|
||||||
// Currently only for Joybus communications
|
// Currently only for Joybus communications
|
||||||
|
|
||||||
GBASockClient::GBASockClient(sf::IPAddress _server_addr)
|
GBASockClient::GBASockClient(sf::IPAddress _server_addr)
|
||||||
{
|
{
|
||||||
if (!_server_addr.IsValid())
|
if (!_server_addr.IsValid())
|
||||||
server_addr = sf::IPAddress::LocalHost;
|
server_addr = sf::IPAddress::LocalHost;
|
||||||
else
|
else
|
||||||
server_addr = _server_addr;
|
server_addr = _server_addr;
|
||||||
|
|
||||||
client.Connect(0xd6ba, server_addr);
|
client.Connect(0xd6ba, server_addr);
|
||||||
//client.SetBlocking(false);
|
//client.SetBlocking(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
GBASockClient::~GBASockClient()
|
GBASockClient::~GBASockClient()
|
||||||
{
|
{
|
||||||
client.Close();
|
client.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBASockClient::Send(std::vector<char> data)
|
void GBASockClient::Send(std::vector<char> data)
|
||||||
{
|
{
|
||||||
char* plain_data = new char[data.size()];
|
char* plain_data = new char[data.size()];
|
||||||
std::copy(data.begin(), data.end(), plain_data);
|
std::copy(data.begin(), data.end(), plain_data);
|
||||||
|
|
||||||
client.Send(plain_data, data.size());
|
client.Send(plain_data, data.size());
|
||||||
|
|
||||||
delete[] plain_data;
|
delete[] plain_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns cmd for convenience
|
// Returns cmd for convenience
|
||||||
char GBASockClient::ReceiveCmd(char* data_in)
|
char GBASockClient::ReceiveCmd(char* data_in)
|
||||||
{
|
{
|
||||||
std::size_t num_received;
|
std::size_t num_received;
|
||||||
client.Receive(data_in, 5, num_received);
|
client.Receive(data_in, 5, num_received);
|
||||||
|
|
||||||
return data_in[0];
|
return data_in[0];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <SFML/Network.hpp>
|
#include <SFML/Network.hpp>
|
||||||
#include "../common/Types.h"
|
#include "../common/Types.h"
|
||||||
|
|
||||||
class GBASockClient : public sf::SocketTCP
|
class GBASockClient : public sf::SocketTCP
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GBASockClient(sf::IPAddress server_addr);
|
GBASockClient(sf::IPAddress server_addr);
|
||||||
~GBASockClient();
|
~GBASockClient();
|
||||||
|
|
||||||
void Send(std::vector<char> data);
|
void Send(std::vector<char> data);
|
||||||
char ReceiveCmd(char* data_in);
|
char ReceiveCmd(char* data_in);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sf::IPAddress server_addr;
|
sf::IPAddress server_addr;
|
||||||
sf::SocketTCP client;
|
sf::SocketTCP client;
|
||||||
};
|
};
|
||||||
|
|
1448
src/gba/GBAinline.h
1448
src/gba/GBAinline.h
File diff suppressed because it is too large
Load Diff
416
src/gba/RTC.cpp
416
src/gba/RTC.cpp
|
@ -1,208 +1,208 @@
|
||||||
#include "../System.h"
|
#include "../System.h"
|
||||||
#include "GBA.h"
|
#include "GBA.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "../common/Port.h"
|
#include "../common/Port.h"
|
||||||
#include "../Util.h"
|
#include "../Util.h"
|
||||||
#include "../NLS.h"
|
#include "../NLS.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
|
||||||
enum RTCSTATE { IDLE, COMMAND, DATA, READDATA };
|
enum RTCSTATE { IDLE, COMMAND, DATA, READDATA };
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u8 byte0;
|
u8 byte0;
|
||||||
u8 byte1;
|
u8 byte1;
|
||||||
u8 byte2;
|
u8 byte2;
|
||||||
u8 command;
|
u8 command;
|
||||||
int dataLen;
|
int dataLen;
|
||||||
int bits;
|
int bits;
|
||||||
RTCSTATE state;
|
RTCSTATE state;
|
||||||
u8 data[12];
|
u8 data[12];
|
||||||
// reserved variables for future
|
// reserved variables for future
|
||||||
u8 reserved[12];
|
u8 reserved[12];
|
||||||
bool reserved2;
|
bool reserved2;
|
||||||
u32 reserved3;
|
u32 reserved3;
|
||||||
} RTCCLOCKDATA;
|
} RTCCLOCKDATA;
|
||||||
|
|
||||||
static RTCCLOCKDATA rtcClockData;
|
static RTCCLOCKDATA rtcClockData;
|
||||||
static bool rtcEnabled = false;
|
static bool rtcEnabled = false;
|
||||||
|
|
||||||
void rtcEnable(bool e)
|
void rtcEnable(bool e)
|
||||||
{
|
{
|
||||||
rtcEnabled = e;
|
rtcEnabled = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtcIsEnabled()
|
bool rtcIsEnabled()
|
||||||
{
|
{
|
||||||
return rtcEnabled;
|
return rtcEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 rtcRead(u32 address)
|
u16 rtcRead(u32 address)
|
||||||
{
|
{
|
||||||
if(rtcEnabled) {
|
if(rtcEnabled) {
|
||||||
switch(address){
|
switch(address){
|
||||||
case 0x80000c8:
|
case 0x80000c8:
|
||||||
return rtcClockData.byte2;
|
return rtcClockData.byte2;
|
||||||
break;
|
break;
|
||||||
case 0x80000c6:
|
case 0x80000c6:
|
||||||
return rtcClockData.byte1;
|
return rtcClockData.byte1;
|
||||||
break;
|
break;
|
||||||
case 0x80000c4:
|
case 0x80000c4:
|
||||||
return rtcClockData.byte0;
|
return rtcClockData.byte0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return READ16LE((&rom[address & 0x1FFFFFE]));
|
return READ16LE((&rom[address & 0x1FFFFFE]));
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 toBCD(u8 value)
|
static u8 toBCD(u8 value)
|
||||||
{
|
{
|
||||||
value = value % 100;
|
value = value % 100;
|
||||||
int l = value % 10;
|
int l = value % 10;
|
||||||
int h = value / 10;
|
int h = value / 10;
|
||||||
return h * 16 + l;
|
return h * 16 + l;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtcWrite(u32 address, u16 value)
|
bool rtcWrite(u32 address, u16 value)
|
||||||
{
|
{
|
||||||
if(!rtcEnabled)
|
if(!rtcEnabled)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(address == 0x80000c8) {
|
if(address == 0x80000c8) {
|
||||||
rtcClockData.byte2 = (u8)value; // enable ?
|
rtcClockData.byte2 = (u8)value; // enable ?
|
||||||
} else if(address == 0x80000c6) {
|
} else if(address == 0x80000c6) {
|
||||||
rtcClockData.byte1 = (u8)value; // read/write
|
rtcClockData.byte1 = (u8)value; // read/write
|
||||||
} else if(address == 0x80000c4) {
|
} else if(address == 0x80000c4) {
|
||||||
if(rtcClockData.byte2 & 1) {
|
if(rtcClockData.byte2 & 1) {
|
||||||
if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) {
|
if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) {
|
||||||
rtcClockData.state = COMMAND;
|
rtcClockData.state = COMMAND;
|
||||||
rtcClockData.bits = 0;
|
rtcClockData.bits = 0;
|
||||||
rtcClockData.command = 0;
|
rtcClockData.command = 0;
|
||||||
} else if(!(rtcClockData.byte0 & 1) && (value & 1)) { // bit transfer
|
} else if(!(rtcClockData.byte0 & 1) && (value & 1)) { // bit transfer
|
||||||
rtcClockData.byte0 = (u8)value;
|
rtcClockData.byte0 = (u8)value;
|
||||||
switch(rtcClockData.state) {
|
switch(rtcClockData.state) {
|
||||||
case COMMAND:
|
case COMMAND:
|
||||||
rtcClockData.command |= ((value & 2) >> 1) << (7-rtcClockData.bits);
|
rtcClockData.command |= ((value & 2) >> 1) << (7-rtcClockData.bits);
|
||||||
rtcClockData.bits++;
|
rtcClockData.bits++;
|
||||||
if(rtcClockData.bits == 8) {
|
if(rtcClockData.bits == 8) {
|
||||||
rtcClockData.bits = 0;
|
rtcClockData.bits = 0;
|
||||||
switch(rtcClockData.command) {
|
switch(rtcClockData.command) {
|
||||||
case 0x60:
|
case 0x60:
|
||||||
// not sure what this command does but it doesn't take parameters
|
// not sure what this command does but it doesn't take parameters
|
||||||
// maybe it is a reset or stop
|
// maybe it is a reset or stop
|
||||||
rtcClockData.state = IDLE;
|
rtcClockData.state = IDLE;
|
||||||
rtcClockData.bits = 0;
|
rtcClockData.bits = 0;
|
||||||
break;
|
break;
|
||||||
case 0x62:
|
case 0x62:
|
||||||
// this sets the control state but not sure what those values are
|
// this sets the control state but not sure what those values are
|
||||||
rtcClockData.state = READDATA;
|
rtcClockData.state = READDATA;
|
||||||
rtcClockData.dataLen = 1;
|
rtcClockData.dataLen = 1;
|
||||||
break;
|
break;
|
||||||
case 0x63:
|
case 0x63:
|
||||||
rtcClockData.dataLen = 1;
|
rtcClockData.dataLen = 1;
|
||||||
rtcClockData.data[0] = 0x40;
|
rtcClockData.data[0] = 0x40;
|
||||||
rtcClockData.state = DATA;
|
rtcClockData.state = DATA;
|
||||||
break;
|
break;
|
||||||
case 0x64:
|
case 0x64:
|
||||||
break;
|
break;
|
||||||
case 0x65:
|
case 0x65:
|
||||||
{
|
{
|
||||||
struct tm *newtime;
|
struct tm *newtime;
|
||||||
time_t long_time;
|
time_t long_time;
|
||||||
|
|
||||||
time( &long_time ); /* Get time as long integer. */
|
time( &long_time ); /* Get time as long integer. */
|
||||||
newtime = localtime( &long_time ); /* Convert to local time. */
|
newtime = localtime( &long_time ); /* Convert to local time. */
|
||||||
|
|
||||||
rtcClockData.dataLen = 7;
|
rtcClockData.dataLen = 7;
|
||||||
rtcClockData.data[0] = toBCD(newtime->tm_year);
|
rtcClockData.data[0] = toBCD(newtime->tm_year);
|
||||||
rtcClockData.data[1] = toBCD(newtime->tm_mon+1);
|
rtcClockData.data[1] = toBCD(newtime->tm_mon+1);
|
||||||
rtcClockData.data[2] = toBCD(newtime->tm_mday);
|
rtcClockData.data[2] = toBCD(newtime->tm_mday);
|
||||||
rtcClockData.data[3] = toBCD(newtime->tm_wday);
|
rtcClockData.data[3] = toBCD(newtime->tm_wday);
|
||||||
rtcClockData.data[4] = toBCD(newtime->tm_hour);
|
rtcClockData.data[4] = toBCD(newtime->tm_hour);
|
||||||
rtcClockData.data[5] = toBCD(newtime->tm_min);
|
rtcClockData.data[5] = toBCD(newtime->tm_min);
|
||||||
rtcClockData.data[6] = toBCD(newtime->tm_sec);
|
rtcClockData.data[6] = toBCD(newtime->tm_sec);
|
||||||
rtcClockData.state = DATA;
|
rtcClockData.state = DATA;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x67:
|
case 0x67:
|
||||||
{
|
{
|
||||||
struct tm *newtime;
|
struct tm *newtime;
|
||||||
time_t long_time;
|
time_t long_time;
|
||||||
|
|
||||||
time( &long_time ); /* Get time as long integer. */
|
time( &long_time ); /* Get time as long integer. */
|
||||||
newtime = localtime( &long_time ); /* Convert to local time. */
|
newtime = localtime( &long_time ); /* Convert to local time. */
|
||||||
|
|
||||||
rtcClockData.dataLen = 3;
|
rtcClockData.dataLen = 3;
|
||||||
rtcClockData.data[0] = toBCD(newtime->tm_hour);
|
rtcClockData.data[0] = toBCD(newtime->tm_hour);
|
||||||
rtcClockData.data[1] = toBCD(newtime->tm_min);
|
rtcClockData.data[1] = toBCD(newtime->tm_min);
|
||||||
rtcClockData.data[2] = toBCD(newtime->tm_sec);
|
rtcClockData.data[2] = toBCD(newtime->tm_sec);
|
||||||
rtcClockData.state = DATA;
|
rtcClockData.state = DATA;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
systemMessage(0, N_("Unknown RTC command %02x"), rtcClockData.command);
|
systemMessage(0, N_("Unknown RTC command %02x"), rtcClockData.command);
|
||||||
rtcClockData.state = IDLE;
|
rtcClockData.state = IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DATA:
|
case DATA:
|
||||||
if(rtcClockData.byte1 & 2) {
|
if(rtcClockData.byte1 & 2) {
|
||||||
} else {
|
} else {
|
||||||
rtcClockData.byte0 = (rtcClockData.byte0 & ~2) |
|
rtcClockData.byte0 = (rtcClockData.byte0 & ~2) |
|
||||||
((rtcClockData.data[rtcClockData.bits >> 3] >>
|
((rtcClockData.data[rtcClockData.bits >> 3] >>
|
||||||
(rtcClockData.bits & 7)) & 1)*2;
|
(rtcClockData.bits & 7)) & 1)*2;
|
||||||
rtcClockData.bits++;
|
rtcClockData.bits++;
|
||||||
if(rtcClockData.bits == 8*rtcClockData.dataLen) {
|
if(rtcClockData.bits == 8*rtcClockData.dataLen) {
|
||||||
rtcClockData.bits = 0;
|
rtcClockData.bits = 0;
|
||||||
rtcClockData.state = IDLE;
|
rtcClockData.state = IDLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case READDATA:
|
case READDATA:
|
||||||
if(!(rtcClockData.byte1 & 2)) {
|
if(!(rtcClockData.byte1 & 2)) {
|
||||||
} else {
|
} else {
|
||||||
rtcClockData.data[rtcClockData.bits >> 3] =
|
rtcClockData.data[rtcClockData.bits >> 3] =
|
||||||
(rtcClockData.data[rtcClockData.bits >> 3] >> 1) |
|
(rtcClockData.data[rtcClockData.bits >> 3] >> 1) |
|
||||||
((value << 6) & 128);
|
((value << 6) & 128);
|
||||||
rtcClockData.bits++;
|
rtcClockData.bits++;
|
||||||
if(rtcClockData.bits == 8*rtcClockData.dataLen) {
|
if(rtcClockData.bits == 8*rtcClockData.dataLen) {
|
||||||
rtcClockData.bits = 0;
|
rtcClockData.bits = 0;
|
||||||
rtcClockData.state = IDLE;
|
rtcClockData.state = IDLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
rtcClockData.byte0 = (u8)value;
|
rtcClockData.byte0 = (u8)value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtcReset()
|
void rtcReset()
|
||||||
{
|
{
|
||||||
memset(&rtcClockData, 0, sizeof(rtcClockData));
|
memset(&rtcClockData, 0, sizeof(rtcClockData));
|
||||||
|
|
||||||
rtcClockData.byte0 = 0;
|
rtcClockData.byte0 = 0;
|
||||||
rtcClockData.byte1 = 0;
|
rtcClockData.byte1 = 0;
|
||||||
rtcClockData.byte2 = 0;
|
rtcClockData.byte2 = 0;
|
||||||
rtcClockData.command = 0;
|
rtcClockData.command = 0;
|
||||||
rtcClockData.dataLen = 0;
|
rtcClockData.dataLen = 0;
|
||||||
rtcClockData.bits = 0;
|
rtcClockData.bits = 0;
|
||||||
rtcClockData.state = IDLE;
|
rtcClockData.state = IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtcSaveGame(gzFile gzFile)
|
void rtcSaveGame(gzFile gzFile)
|
||||||
{
|
{
|
||||||
utilGzWrite(gzFile, &rtcClockData, sizeof(rtcClockData));
|
utilGzWrite(gzFile, &rtcClockData, sizeof(rtcClockData));
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtcReadGame(gzFile gzFile)
|
void rtcReadGame(gzFile gzFile)
|
||||||
{
|
{
|
||||||
utilGzRead(gzFile, &rtcClockData, sizeof(rtcClockData));
|
utilGzRead(gzFile, &rtcClockData, sizeof(rtcClockData));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#ifndef RTC_H
|
#ifndef RTC_H
|
||||||
#define RTC_H
|
#define RTC_H
|
||||||
|
|
||||||
u16 rtcRead(u32 address);
|
u16 rtcRead(u32 address);
|
||||||
bool rtcWrite(u32 address, u16 value);
|
bool rtcWrite(u32 address, u16 value);
|
||||||
void rtcEnable(bool);
|
void rtcEnable(bool);
|
||||||
bool rtcIsEnabled();
|
bool rtcIsEnabled();
|
||||||
void rtcReset();
|
void rtcReset();
|
||||||
|
|
||||||
void rtcReadGame(gzFile gzFile);
|
void rtcReadGame(gzFile gzFile);
|
||||||
void rtcSaveGame(gzFile gzFile);
|
void rtcSaveGame(gzFile gzFile);
|
||||||
|
|
||||||
#endif // RTC_H
|
#endif // RTC_H
|
||||||
|
|
|
@ -1,227 +1,227 @@
|
||||||
#include "gbafilter.h"
|
#include "gbafilter.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
extern int systemColorDepth;
|
extern int systemColorDepth;
|
||||||
extern int systemRedShift;
|
extern int systemRedShift;
|
||||||
extern int systemGreenShift;
|
extern int systemGreenShift;
|
||||||
extern int systemBlueShift;
|
extern int systemBlueShift;
|
||||||
|
|
||||||
extern u16 systemColorMap16[0x10000];
|
extern u16 systemColorMap16[0x10000];
|
||||||
extern u32 systemColorMap32[0x10000];
|
extern u32 systemColorMap32[0x10000];
|
||||||
|
|
||||||
static const unsigned char curve[32] = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x10, 0x12,
|
static const unsigned char curve[32] = { 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x10, 0x12,
|
||||||
0x14, 0x16, 0x18, 0x1c, 0x20, 0x28, 0x30, 0x38,
|
0x14, 0x16, 0x18, 0x1c, 0x20, 0x28, 0x30, 0x38,
|
||||||
0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x80,
|
0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x80,
|
||||||
0x88, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0};
|
0x88, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0};
|
||||||
|
|
||||||
// output R G B
|
// output R G B
|
||||||
static const unsigned char influence[3 * 3] = { 16, 4, 4, // red
|
static const unsigned char influence[3 * 3] = { 16, 4, 4, // red
|
||||||
8, 16, 8, // green
|
8, 16, 8, // green
|
||||||
0, 8, 16};// blue
|
0, 8, 16};// blue
|
||||||
|
|
||||||
inline void swap(short & a, short & b)
|
inline void swap(short & a, short & b)
|
||||||
{
|
{
|
||||||
short temp = a;
|
short temp = a;
|
||||||
a = b;
|
a = b;
|
||||||
b = temp;
|
b = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbafilter_pal(u16 * buf, int count)
|
void gbafilter_pal(u16 * buf, int count)
|
||||||
{
|
{
|
||||||
short temp[3 * 3], s;
|
short temp[3 * 3], s;
|
||||||
unsigned pix;
|
unsigned pix;
|
||||||
u8 red, green, blue;
|
u8 red, green, blue;
|
||||||
|
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
pix = *buf;
|
pix = *buf;
|
||||||
|
|
||||||
s = curve[(pix >> systemGreenShift) & 0x1f];
|
s = curve[(pix >> systemGreenShift) & 0x1f];
|
||||||
temp[3] = s * influence[3];
|
temp[3] = s * influence[3];
|
||||||
temp[4] = s * influence[4];
|
temp[4] = s * influence[4];
|
||||||
temp[5] = s * influence[5];
|
temp[5] = s * influence[5];
|
||||||
|
|
||||||
s = curve[(pix >> systemRedShift) & 0x1f];
|
s = curve[(pix >> systemRedShift) & 0x1f];
|
||||||
temp[0] = s * influence[0];
|
temp[0] = s * influence[0];
|
||||||
temp[1] = s * influence[1];
|
temp[1] = s * influence[1];
|
||||||
temp[2] = s * influence[2];
|
temp[2] = s * influence[2];
|
||||||
|
|
||||||
s = curve[(pix >> systemBlueShift) & 0x1f];
|
s = curve[(pix >> systemBlueShift) & 0x1f];
|
||||||
temp[6] = s * influence[6];
|
temp[6] = s * influence[6];
|
||||||
temp[7] = s * influence[7];
|
temp[7] = s * influence[7];
|
||||||
temp[8] = s * influence[8];
|
temp[8] = s * influence[8];
|
||||||
|
|
||||||
if (temp[0] < temp[3]) swap(temp[0], temp[3]);
|
if (temp[0] < temp[3]) swap(temp[0], temp[3]);
|
||||||
if (temp[0] < temp[6]) swap(temp[0], temp[6]);
|
if (temp[0] < temp[6]) swap(temp[0], temp[6]);
|
||||||
if (temp[3] < temp[6]) swap(temp[3], temp[6]);
|
if (temp[3] < temp[6]) swap(temp[3], temp[6]);
|
||||||
temp[3] <<= 1;
|
temp[3] <<= 1;
|
||||||
temp[0] <<= 2;
|
temp[0] <<= 2;
|
||||||
temp[0] += temp[3] + temp[6];
|
temp[0] += temp[3] + temp[6];
|
||||||
|
|
||||||
red = ((int(temp[0]) * 160) >> 17) + 4;
|
red = ((int(temp[0]) * 160) >> 17) + 4;
|
||||||
if (red > 31) red = 31;
|
if (red > 31) red = 31;
|
||||||
|
|
||||||
if (temp[2] < temp[5]) swap(temp[2], temp[5]);
|
if (temp[2] < temp[5]) swap(temp[2], temp[5]);
|
||||||
if (temp[2] < temp[8]) swap(temp[2], temp[8]);
|
if (temp[2] < temp[8]) swap(temp[2], temp[8]);
|
||||||
if (temp[5] < temp[8]) swap(temp[5], temp[8]);
|
if (temp[5] < temp[8]) swap(temp[5], temp[8]);
|
||||||
temp[5] <<= 1;
|
temp[5] <<= 1;
|
||||||
temp[2] <<= 2;
|
temp[2] <<= 2;
|
||||||
temp[2] += temp[5] + temp[8];
|
temp[2] += temp[5] + temp[8];
|
||||||
|
|
||||||
blue = ((int(temp[2]) * 160) >> 17) + 4;
|
blue = ((int(temp[2]) * 160) >> 17) + 4;
|
||||||
if (blue > 31) blue = 31;
|
if (blue > 31) blue = 31;
|
||||||
|
|
||||||
if (temp[1] < temp[4]) swap(temp[1], temp[4]);
|
if (temp[1] < temp[4]) swap(temp[1], temp[4]);
|
||||||
if (temp[1] < temp[7]) swap(temp[1], temp[7]);
|
if (temp[1] < temp[7]) swap(temp[1], temp[7]);
|
||||||
if (temp[4] < temp[7]) swap(temp[4], temp[7]);
|
if (temp[4] < temp[7]) swap(temp[4], temp[7]);
|
||||||
temp[4] <<= 1;
|
temp[4] <<= 1;
|
||||||
temp[1] <<= 2;
|
temp[1] <<= 2;
|
||||||
temp[1] += temp[4] + temp[7];
|
temp[1] += temp[4] + temp[7];
|
||||||
|
|
||||||
green = ((int(temp[1]) * 160) >> 17) + 4;
|
green = ((int(temp[1]) * 160) >> 17) + 4;
|
||||||
if (green > 31) green = 31;
|
if (green > 31) green = 31;
|
||||||
|
|
||||||
pix = red << systemRedShift;
|
pix = red << systemRedShift;
|
||||||
pix += green << systemGreenShift;
|
pix += green << systemGreenShift;
|
||||||
pix += blue << systemBlueShift;
|
pix += blue << systemBlueShift;
|
||||||
|
|
||||||
*buf++ = pix;
|
*buf++ = pix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gbafilter_pal32(u32 * buf, int count)
|
void gbafilter_pal32(u32 * buf, int count)
|
||||||
{
|
{
|
||||||
short temp[3 * 3], s;
|
short temp[3 * 3], s;
|
||||||
unsigned pix;
|
unsigned pix;
|
||||||
u8 red, green, blue;
|
u8 red, green, blue;
|
||||||
|
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
pix = *buf;
|
pix = *buf;
|
||||||
|
|
||||||
s = curve[(pix >> systemGreenShift) & 0x1f];
|
s = curve[(pix >> systemGreenShift) & 0x1f];
|
||||||
temp[3] = s * influence[3];
|
temp[3] = s * influence[3];
|
||||||
temp[4] = s * influence[4];
|
temp[4] = s * influence[4];
|
||||||
temp[5] = s * influence[5];
|
temp[5] = s * influence[5];
|
||||||
|
|
||||||
s = curve[(pix >> systemRedShift) & 0x1f];
|
s = curve[(pix >> systemRedShift) & 0x1f];
|
||||||
temp[0] = s * influence[0];
|
temp[0] = s * influence[0];
|
||||||
temp[1] = s * influence[1];
|
temp[1] = s * influence[1];
|
||||||
temp[2] = s * influence[2];
|
temp[2] = s * influence[2];
|
||||||
|
|
||||||
s = curve[(pix >> systemBlueShift) & 0x1f];
|
s = curve[(pix >> systemBlueShift) & 0x1f];
|
||||||
temp[6] = s * influence[6];
|
temp[6] = s * influence[6];
|
||||||
temp[7] = s * influence[7];
|
temp[7] = s * influence[7];
|
||||||
temp[8] = s * influence[8];
|
temp[8] = s * influence[8];
|
||||||
|
|
||||||
if (temp[0] < temp[3]) swap(temp[0], temp[3]);
|
if (temp[0] < temp[3]) swap(temp[0], temp[3]);
|
||||||
if (temp[0] < temp[6]) swap(temp[0], temp[6]);
|
if (temp[0] < temp[6]) swap(temp[0], temp[6]);
|
||||||
if (temp[3] < temp[6]) swap(temp[3], temp[6]);
|
if (temp[3] < temp[6]) swap(temp[3], temp[6]);
|
||||||
temp[3] <<= 1;
|
temp[3] <<= 1;
|
||||||
temp[0] <<= 2;
|
temp[0] <<= 2;
|
||||||
temp[0] += temp[3] + temp[6];
|
temp[0] += temp[3] + temp[6];
|
||||||
|
|
||||||
//red = ((int(temp[0]) * 160) >> 17) + 4;
|
//red = ((int(temp[0]) * 160) >> 17) + 4;
|
||||||
red = ((int(temp[0]) * 160) >> 14) + 32;
|
red = ((int(temp[0]) * 160) >> 14) + 32;
|
||||||
|
|
||||||
if (temp[2] < temp[5]) swap(temp[2], temp[5]);
|
if (temp[2] < temp[5]) swap(temp[2], temp[5]);
|
||||||
if (temp[2] < temp[8]) swap(temp[2], temp[8]);
|
if (temp[2] < temp[8]) swap(temp[2], temp[8]);
|
||||||
if (temp[5] < temp[8]) swap(temp[5], temp[8]);
|
if (temp[5] < temp[8]) swap(temp[5], temp[8]);
|
||||||
temp[5] <<= 1;
|
temp[5] <<= 1;
|
||||||
temp[2] <<= 2;
|
temp[2] <<= 2;
|
||||||
temp[2] += temp[5] + temp[8];
|
temp[2] += temp[5] + temp[8];
|
||||||
|
|
||||||
//blue = ((int(temp[2]) * 160) >> 17) + 4;
|
//blue = ((int(temp[2]) * 160) >> 17) + 4;
|
||||||
blue = ((int(temp[2]) * 160) >> 14) + 32;
|
blue = ((int(temp[2]) * 160) >> 14) + 32;
|
||||||
|
|
||||||
if (temp[1] < temp[4]) swap(temp[1], temp[4]);
|
if (temp[1] < temp[4]) swap(temp[1], temp[4]);
|
||||||
if (temp[1] < temp[7]) swap(temp[1], temp[7]);
|
if (temp[1] < temp[7]) swap(temp[1], temp[7]);
|
||||||
if (temp[4] < temp[7]) swap(temp[4], temp[7]);
|
if (temp[4] < temp[7]) swap(temp[4], temp[7]);
|
||||||
temp[4] <<= 1;
|
temp[4] <<= 1;
|
||||||
temp[1] <<= 2;
|
temp[1] <<= 2;
|
||||||
temp[1] += temp[4] + temp[7];
|
temp[1] += temp[4] + temp[7];
|
||||||
|
|
||||||
//green = ((int(temp[1]) * 160) >> 17) + 4;
|
//green = ((int(temp[1]) * 160) >> 17) + 4;
|
||||||
green = ((int(temp[1]) * 160) >> 14) + 32;
|
green = ((int(temp[1]) * 160) >> 14) + 32;
|
||||||
|
|
||||||
//pix = red << redshift;
|
//pix = red << redshift;
|
||||||
//pix += green << greenshift;
|
//pix += green << greenshift;
|
||||||
//pix += blue << blueshift;
|
//pix += blue << blueshift;
|
||||||
|
|
||||||
pix = red << (systemRedShift - 3);
|
pix = red << (systemRedShift - 3);
|
||||||
pix += green << (systemGreenShift - 3);
|
pix += green << (systemGreenShift - 3);
|
||||||
pix += blue << (systemBlueShift - 3);
|
pix += blue << (systemBlueShift - 3);
|
||||||
|
|
||||||
*buf++ = pix;
|
*buf++ = pix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for palette mode to work with the three spoony filters in 32bpp depth
|
// for palette mode to work with the three spoony filters in 32bpp depth
|
||||||
|
|
||||||
void gbafilter_pad(u8 * buf, int count)
|
void gbafilter_pad(u8 * buf, int count)
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
u8 r;
|
u8 r;
|
||||||
u8 g;
|
u8 g;
|
||||||
u8 b;
|
u8 b;
|
||||||
u8 a;
|
u8 a;
|
||||||
} part;
|
} part;
|
||||||
unsigned whole;
|
unsigned whole;
|
||||||
}
|
}
|
||||||
mask;
|
mask;
|
||||||
|
|
||||||
mask.whole = 0x1f << systemRedShift;
|
mask.whole = 0x1f << systemRedShift;
|
||||||
mask.whole += 0x1f << systemGreenShift;
|
mask.whole += 0x1f << systemGreenShift;
|
||||||
mask.whole += 0x1f << systemBlueShift;
|
mask.whole += 0x1f << systemBlueShift;
|
||||||
|
|
||||||
switch (systemColorDepth)
|
switch (systemColorDepth)
|
||||||
{
|
{
|
||||||
case 24:
|
case 24:
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
*buf++ &= mask.part.r;
|
*buf++ &= mask.part.r;
|
||||||
*buf++ &= mask.part.g;
|
*buf++ &= mask.part.g;
|
||||||
*buf++ &= mask.part.b;
|
*buf++ &= mask.part.b;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
*((u32*)buf) &= mask.whole;
|
*((u32*)buf) &= mask.whole;
|
||||||
buf += 4;
|
buf += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void UpdateSystemColorMaps(int lcd)
|
void UpdateSystemColorMaps(int lcd)
|
||||||
{
|
{
|
||||||
switch(systemColorDepth) {
|
switch(systemColorDepth) {
|
||||||
case 16:
|
case 16:
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 0x10000; i++) {
|
for(int i = 0; i < 0x10000; i++) {
|
||||||
systemColorMap16[i] = ((i & 0x1f) << systemRedShift) |
|
systemColorMap16[i] = ((i & 0x1f) << systemRedShift) |
|
||||||
(((i & 0x3e0) >> 5) << systemGreenShift) |
|
(((i & 0x3e0) >> 5) << systemGreenShift) |
|
||||||
(((i & 0x7c00) >> 10) << systemBlueShift);
|
(((i & 0x7c00) >> 10) << systemBlueShift);
|
||||||
}
|
}
|
||||||
if (lcd == 1) gbafilter_pal(systemColorMap16, 0x10000);
|
if (lcd == 1) gbafilter_pal(systemColorMap16, 0x10000);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
case 32:
|
case 32:
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 0x10000; i++) {
|
for(int i = 0; i < 0x10000; i++) {
|
||||||
systemColorMap32[i] = ((i & 0x1f) << systemRedShift) |
|
systemColorMap32[i] = ((i & 0x1f) << systemRedShift) |
|
||||||
(((i & 0x3e0) >> 5) << systemGreenShift) |
|
(((i & 0x3e0) >> 5) << systemGreenShift) |
|
||||||
(((i & 0x7c00) >> 10) << systemBlueShift);
|
(((i & 0x7c00) >> 10) << systemBlueShift);
|
||||||
}
|
}
|
||||||
if (lcd == 1) gbafilter_pal32(systemColorMap32, 0x10000);
|
if (lcd == 1) gbafilter_pal32(systemColorMap32, 0x10000);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "../System.h"
|
#include "../System.h"
|
||||||
|
|
||||||
void gbafilter_pal(u16 * buf, int count);
|
void gbafilter_pal(u16 * buf, int count);
|
||||||
void gbafilter_pal32(u32 * buf, int count);
|
void gbafilter_pal32(u32 * buf, int count);
|
||||||
void gbafilter_pad(u8 * buf, int count);
|
void gbafilter_pad(u8 * buf, int count);
|
||||||
|
|
1242
src/sdl/inputSDL.cpp
1242
src/sdl/inputSDL.cpp
File diff suppressed because it is too large
Load Diff
114
src/version.h
114
src/version.h
|
@ -1,57 +1,57 @@
|
||||||
// -*- C++ -*-
|
// -*- C++ -*-
|
||||||
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
||||||
// Copyright (C) 1999-2003 Forgotten
|
// Copyright (C) 1999-2003 Forgotten
|
||||||
// Copyright (C) 2004 Forgotten and the VBA development team
|
// Copyright (C) 2004 Forgotten and the VBA development team
|
||||||
|
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU General Public License as published by
|
// it under the terms of the GNU General Public License as published by
|
||||||
// the Free Software Foundation; either version 2, or(at your option)
|
// the Free Software Foundation; either version 2, or(at your option)
|
||||||
// any later version.
|
// any later version.
|
||||||
//
|
//
|
||||||
// This program is distributed in the hope that it will be useful,
|
// This program is distributed in the hope that it will be useful,
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
// GNU General Public License for more details.
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program; if not, write to the Free Software Foundation,
|
// along with this program; if not, write to the Free Software Foundation,
|
||||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#define VBA_NAME "VisualBoyAdvance-M"
|
#define VBA_NAME "VisualBoyAdvance-M"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include "svnrev.h"
|
#include "svnrev.h"
|
||||||
#else
|
#else
|
||||||
#ifdef SVN_REV
|
#ifdef SVN_REV
|
||||||
#define SVN_REV_STR SVN_REV
|
#define SVN_REV_STR SVN_REV
|
||||||
#else
|
#else
|
||||||
#define SVN_REV_STR ""
|
#define SVN_REV_STR ""
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define VBA_FEATURE_STRING ""
|
#define VBA_FEATURE_STRING ""
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define VBA_SUBVERSION_STRING " debug"
|
#define VBA_SUBVERSION_STRING " debug"
|
||||||
#elif defined(PUBLIC_RELEASE)
|
#elif defined(PUBLIC_RELEASE)
|
||||||
#define VBA_SUBVERSION_STRING ""
|
#define VBA_SUBVERSION_STRING ""
|
||||||
#else
|
#else
|
||||||
#define VBA_SUBVERSION_STRING " (SVN" SVN_REV_STR ")"
|
#define VBA_SUBVERSION_STRING " (SVN" SVN_REV_STR ")"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#define VBA_COMPILER ""
|
#define VBA_COMPILER ""
|
||||||
#define VBA_COMPILER_DETAIL " msvc " _Py_STRINGIZE(_MSC_VER)
|
#define VBA_COMPILER_DETAIL " msvc " _Py_STRINGIZE(_MSC_VER)
|
||||||
#define _Py_STRINGIZE(X) _Py_STRINGIZE1((X))
|
#define _Py_STRINGIZE(X) _Py_STRINGIZE1((X))
|
||||||
#define _Py_STRINGIZE1(X) _Py_STRINGIZE2 ## X
|
#define _Py_STRINGIZE1(X) _Py_STRINGIZE2 ## X
|
||||||
#define _Py_STRINGIZE2(X) #X
|
#define _Py_STRINGIZE2(X) #X
|
||||||
//re: http://72.14.203.104/search?q=cache:HG-okth5NGkJ:mail.python.org/pipermail/python-checkins/2002-November/030704.html+_msc_ver+compiler+version+string&hl=en&gl=us&ct=clnk&cd=5
|
//re: http://72.14.203.104/search?q=cache:HG-okth5NGkJ:mail.python.org/pipermail/python-checkins/2002-November/030704.html+_msc_ver+compiler+version+string&hl=en&gl=us&ct=clnk&cd=5
|
||||||
#else
|
#else
|
||||||
// TODO: make for others compilers
|
// TODO: make for others compilers
|
||||||
#define VBA_COMPILER ""
|
#define VBA_COMPILER ""
|
||||||
#define VBA_COMPILER_DETAIL ""
|
#define VBA_COMPILER_DETAIL ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define VBA_VERSION_STRING " " "1.8.0" VBA_SUBVERSION_STRING VBA_FEATURE_STRING VBA_COMPILER
|
#define VBA_VERSION_STRING " " "1.8.0" VBA_SUBVERSION_STRING VBA_FEATURE_STRING VBA_COMPILER
|
||||||
#define VBA_NAME_AND_VERSION " " VBA_NAME VBA_VERSION_STRING
|
#define VBA_NAME_AND_VERSION " " VBA_NAME VBA_VERSION_STRING
|
||||||
#define VBA_NAME_AND_SUBVERSION " " VBA_NAME VBA_SUBVERSION_STRING
|
#define VBA_NAME_AND_SUBVERSION " " VBA_NAME VBA_SUBVERSION_STRING
|
||||||
|
|
|
@ -1,191 +1,191 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "VBA.h"
|
#include "VBA.h"
|
||||||
|
|
||||||
#include "AudioCoreSettingsDlg.h"
|
#include "AudioCoreSettingsDlg.h"
|
||||||
|
|
||||||
#define MIN_VOLUME 0.0f
|
#define MIN_VOLUME 0.0f
|
||||||
#define MAX_VOLUME 4.0f
|
#define MAX_VOLUME 4.0f
|
||||||
|
|
||||||
|
|
||||||
// AudioCoreSettingsDlg dialog
|
// AudioCoreSettingsDlg dialog
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC(AudioCoreSettingsDlg, CDialog)
|
IMPLEMENT_DYNAMIC(AudioCoreSettingsDlg, CDialog)
|
||||||
|
|
||||||
AudioCoreSettingsDlg::AudioCoreSettingsDlg(CWnd* pParent /*=NULL*/)
|
AudioCoreSettingsDlg::AudioCoreSettingsDlg(CWnd* pParent /*=NULL*/)
|
||||||
: CDialog(AudioCoreSettingsDlg::IDD, pParent)
|
: CDialog(AudioCoreSettingsDlg::IDD, pParent)
|
||||||
, m_enabled( false )
|
, m_enabled( false )
|
||||||
, m_surround( false )
|
, m_surround( false )
|
||||||
, m_declicking( false )
|
, m_declicking( false )
|
||||||
, m_sound_interpolation( false )
|
, m_sound_interpolation( false )
|
||||||
, m_echo( 0.0f )
|
, m_echo( 0.0f )
|
||||||
, m_stereo( 0.0f )
|
, m_stereo( 0.0f )
|
||||||
, m_volume( 0.0f )
|
, m_volume( 0.0f )
|
||||||
, m_sound_filtering( 0.0f )
|
, m_sound_filtering( 0.0f )
|
||||||
, m_sample_rate( 0 )
|
, m_sample_rate( 0 )
|
||||||
, toolTip( NULL )
|
, toolTip( NULL )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioCoreSettingsDlg::~AudioCoreSettingsDlg()
|
AudioCoreSettingsDlg::~AudioCoreSettingsDlg()
|
||||||
{
|
{
|
||||||
delete toolTip;
|
delete toolTip;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioCoreSettingsDlg::DoDataExchange(CDataExchange* pDX)
|
void AudioCoreSettingsDlg::DoDataExchange(CDataExchange* pDX)
|
||||||
{
|
{
|
||||||
CDialog::DoDataExchange(pDX);
|
CDialog::DoDataExchange(pDX);
|
||||||
|
|
||||||
DDX_Control(pDX, IDC_ENHANCE_SOUND, enhance_sound);
|
DDX_Control(pDX, IDC_ENHANCE_SOUND, enhance_sound);
|
||||||
DDX_Control(pDX, IDC_SURROUND, surround);
|
DDX_Control(pDX, IDC_SURROUND, surround);
|
||||||
DDX_Control(pDX, IDC_ECHO, echo);
|
DDX_Control(pDX, IDC_ECHO, echo);
|
||||||
DDX_Control(pDX, IDC_STEREO, stereo);
|
DDX_Control(pDX, IDC_STEREO, stereo);
|
||||||
DDX_Control(pDX, IDC_VOLUME, volume);
|
DDX_Control(pDX, IDC_VOLUME, volume);
|
||||||
DDX_Control(pDX, IDC_DECLICKING, declicking);
|
DDX_Control(pDX, IDC_DECLICKING, declicking);
|
||||||
DDX_Control(pDX, IDC_SOUND_INTERPOLATION, sound_interpolation);
|
DDX_Control(pDX, IDC_SOUND_INTERPOLATION, sound_interpolation);
|
||||||
DDX_Control(pDX, IDC_SOUND_FILTERING, sound_filtering);
|
DDX_Control(pDX, IDC_SOUND_FILTERING, sound_filtering);
|
||||||
DDX_Control(pDX, IDC_SAMPLE_RATE, sample_rate);
|
DDX_Control(pDX, IDC_SAMPLE_RATE, sample_rate);
|
||||||
|
|
||||||
if( pDX->m_bSaveAndValidate == TRUE ) {
|
if( pDX->m_bSaveAndValidate == TRUE ) {
|
||||||
m_enabled = BST_CHECKED == enhance_sound.GetCheck();
|
m_enabled = BST_CHECKED == enhance_sound.GetCheck();
|
||||||
m_surround = BST_CHECKED == surround.GetCheck();
|
m_surround = BST_CHECKED == surround.GetCheck();
|
||||||
m_declicking = BST_CHECKED == declicking.GetCheck();
|
m_declicking = BST_CHECKED == declicking.GetCheck();
|
||||||
m_sound_interpolation = BST_CHECKED == sound_interpolation.GetCheck();
|
m_sound_interpolation = BST_CHECKED == sound_interpolation.GetCheck();
|
||||||
m_echo = (float)echo.GetPos() / 100.0f;
|
m_echo = (float)echo.GetPos() / 100.0f;
|
||||||
m_stereo = (float)stereo.GetPos() / 100.0f;
|
m_stereo = (float)stereo.GetPos() / 100.0f;
|
||||||
m_volume = (float)volume.GetPos() / 100.0f;
|
m_volume = (float)volume.GetPos() / 100.0f;
|
||||||
m_sound_filtering = (float)sound_filtering.GetPos() / 100.0f;
|
m_sound_filtering = (float)sound_filtering.GetPos() / 100.0f;
|
||||||
m_sample_rate = (unsigned int)sample_rate.GetItemData( sample_rate.GetCurSel() );
|
m_sample_rate = (unsigned int)sample_rate.GetItemData( sample_rate.GetCurSel() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL AudioCoreSettingsDlg::OnTtnNeedText(UINT id, NMHDR *pNMHDR, LRESULT *pResult)
|
BOOL AudioCoreSettingsDlg::OnTtnNeedText(UINT id, NMHDR *pNMHDR, LRESULT *pResult)
|
||||||
{
|
{
|
||||||
TOOLTIPTEXT *t3 = (TOOLTIPTEXT *)pNMHDR; // dirty Windows API
|
TOOLTIPTEXT *t3 = (TOOLTIPTEXT *)pNMHDR; // dirty Windows API
|
||||||
BOOL i_provided_tooltip_with_text = TRUE;
|
BOOL i_provided_tooltip_with_text = TRUE;
|
||||||
|
|
||||||
if( !( t3->uFlags & TTF_IDISHWND ) ) {
|
if( !( t3->uFlags & TTF_IDISHWND ) ) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
// even dirtier Windows API:
|
// even dirtier Windows API:
|
||||||
// t3->hdr.idFrom is actually a HWND, holy cow, why?
|
// t3->hdr.idFrom is actually a HWND, holy cow, why?
|
||||||
// The other case does not even occur.
|
// The other case does not even occur.
|
||||||
int controlID = ::GetDlgCtrlID( (HWND)t3->hdr.idFrom );
|
int controlID = ::GetDlgCtrlID( (HWND)t3->hdr.idFrom );
|
||||||
CString res;
|
CString res;
|
||||||
TCHAR buf[0x400]; // Use own string buffer because szText has an 80 char limit.
|
TCHAR buf[0x400]; // Use own string buffer because szText has an 80 char limit.
|
||||||
// We can't use a dynamic buffer size because Windows does some shady things with
|
// We can't use a dynamic buffer size because Windows does some shady things with
|
||||||
// t3->lpszText at the end of this function, so we have no chance to free the buffer
|
// t3->lpszText at the end of this function, so we have no chance to free the buffer
|
||||||
// before the end of this function.
|
// before the end of this function.
|
||||||
|
|
||||||
switch( controlID ) {
|
switch( controlID ) {
|
||||||
case IDC_VOLUME:
|
case IDC_VOLUME:
|
||||||
_stprintf_s( t3->szText, _countof( t3->szText ), _T( "%i%%" ), volume.GetPos() );
|
_stprintf_s( t3->szText, _countof( t3->szText ), _T( "%i%%" ), volume.GetPos() );
|
||||||
break;
|
break;
|
||||||
case IDC_ECHO:
|
case IDC_ECHO:
|
||||||
_stprintf_s( t3->szText, _countof( t3->szText ), _T( "%i%%" ), echo.GetPos() );
|
_stprintf_s( t3->szText, _countof( t3->szText ), _T( "%i%%" ), echo.GetPos() );
|
||||||
break;
|
break;
|
||||||
case IDC_STEREO:
|
case IDC_STEREO:
|
||||||
_stprintf_s( t3->szText, _countof( t3->szText ), _T( "%i%%" ), stereo.GetPos() );
|
_stprintf_s( t3->szText, _countof( t3->szText ), _T( "%i%%" ), stereo.GetPos() );
|
||||||
break;
|
break;
|
||||||
case IDC_SOUND_FILTERING:
|
case IDC_SOUND_FILTERING:
|
||||||
_stprintf_s( t3->szText, _countof( t3->szText ), _T( "%i%%" ), sound_filtering.GetPos() );
|
_stprintf_s( t3->szText, _countof( t3->szText ), _T( "%i%%" ), sound_filtering.GetPos() );
|
||||||
break;
|
break;
|
||||||
case IDC_DEFAULT_VOLUME:
|
case IDC_DEFAULT_VOLUME:
|
||||||
res.LoadString( IDS_TOOLTIP_DEFAULT_VOLUME );
|
res.LoadString( IDS_TOOLTIP_DEFAULT_VOLUME );
|
||||||
_tcscpy_s( buf, _countof( buf ), res.GetString() );
|
_tcscpy_s( buf, _countof( buf ), res.GetString() );
|
||||||
t3->lpszText = buf;
|
t3->lpszText = buf;
|
||||||
break;
|
break;
|
||||||
case IDC_ENHANCE_SOUND:
|
case IDC_ENHANCE_SOUND:
|
||||||
res.LoadString( IDS_TOOLTIP_ENHANCE_SOUND );
|
res.LoadString( IDS_TOOLTIP_ENHANCE_SOUND );
|
||||||
_tcscpy_s( buf, _countof( buf ), res.GetString() );
|
_tcscpy_s( buf, _countof( buf ), res.GetString() );
|
||||||
t3->lpszText = buf;
|
t3->lpszText = buf;
|
||||||
break;
|
break;
|
||||||
case IDC_SURROUND:
|
case IDC_SURROUND:
|
||||||
res.LoadString( IDS_TOOLTIP_SURROUND );
|
res.LoadString( IDS_TOOLTIP_SURROUND );
|
||||||
_tcscpy_s( buf, _countof( buf ), res.GetString() );
|
_tcscpy_s( buf, _countof( buf ), res.GetString() );
|
||||||
t3->lpszText = buf;
|
t3->lpszText = buf;
|
||||||
break;
|
break;
|
||||||
case IDC_DECLICKING:
|
case IDC_DECLICKING:
|
||||||
res.LoadString( IDS_TOOLTIP_DECLICKING );
|
res.LoadString( IDS_TOOLTIP_DECLICKING );
|
||||||
_tcscpy_s( buf, _countof( buf ), res.GetString() );
|
_tcscpy_s( buf, _countof( buf ), res.GetString() );
|
||||||
t3->lpszText = buf;
|
t3->lpszText = buf;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
i_provided_tooltip_with_text = FALSE;
|
i_provided_tooltip_with_text = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return i_provided_tooltip_with_text;
|
return i_provided_tooltip_with_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BEGIN_MESSAGE_MAP(AudioCoreSettingsDlg, CDialog)
|
BEGIN_MESSAGE_MAP(AudioCoreSettingsDlg, CDialog)
|
||||||
ON_NOTIFY_EX(TTN_NEEDTEXT, 0, &AudioCoreSettingsDlg::OnTtnNeedText)
|
ON_NOTIFY_EX(TTN_NEEDTEXT, 0, &AudioCoreSettingsDlg::OnTtnNeedText)
|
||||||
ON_BN_CLICKED(IDC_DEFAULT_VOLUME, &AudioCoreSettingsDlg::OnBnClickedDefaultVolume)
|
ON_BN_CLICKED(IDC_DEFAULT_VOLUME, &AudioCoreSettingsDlg::OnBnClickedDefaultVolume)
|
||||||
END_MESSAGE_MAP()
|
END_MESSAGE_MAP()
|
||||||
|
|
||||||
|
|
||||||
// AudioCoreSettingsDlg message handlers
|
// AudioCoreSettingsDlg message handlers
|
||||||
|
|
||||||
BOOL AudioCoreSettingsDlg::OnInitDialog()
|
BOOL AudioCoreSettingsDlg::OnInitDialog()
|
||||||
{
|
{
|
||||||
CDialog::OnInitDialog();
|
CDialog::OnInitDialog();
|
||||||
|
|
||||||
// Set up tooltip control
|
// Set up tooltip control
|
||||||
toolTip = new CToolTipCtrl;
|
toolTip = new CToolTipCtrl;
|
||||||
toolTip->Create( this );
|
toolTip->Create( this );
|
||||||
toolTip->AddTool( GetDlgItem( IDC_DEFAULT_VOLUME ) );
|
toolTip->AddTool( GetDlgItem( IDC_DEFAULT_VOLUME ) );
|
||||||
toolTip->AddTool( GetDlgItem( IDC_ENHANCE_SOUND ) );
|
toolTip->AddTool( GetDlgItem( IDC_ENHANCE_SOUND ) );
|
||||||
toolTip->AddTool( GetDlgItem( IDC_SURROUND ) );
|
toolTip->AddTool( GetDlgItem( IDC_SURROUND ) );
|
||||||
toolTip->AddTool( GetDlgItem( IDC_DECLICKING ) );
|
toolTip->AddTool( GetDlgItem( IDC_DECLICKING ) );
|
||||||
toolTip->Activate( TRUE );
|
toolTip->Activate( TRUE );
|
||||||
|
|
||||||
enhance_sound.SetCheck( m_enabled ? BST_CHECKED : BST_UNCHECKED );
|
enhance_sound.SetCheck( m_enabled ? BST_CHECKED : BST_UNCHECKED );
|
||||||
|
|
||||||
surround.SetCheck( m_surround ? BST_CHECKED : BST_UNCHECKED );
|
surround.SetCheck( m_surround ? BST_CHECKED : BST_UNCHECKED );
|
||||||
|
|
||||||
declicking.SetCheck( m_declicking ? BST_CHECKED : BST_UNCHECKED );
|
declicking.SetCheck( m_declicking ? BST_CHECKED : BST_UNCHECKED );
|
||||||
|
|
||||||
sound_interpolation.SetCheck( m_sound_interpolation ? BST_CHECKED : BST_UNCHECKED );
|
sound_interpolation.SetCheck( m_sound_interpolation ? BST_CHECKED : BST_UNCHECKED );
|
||||||
|
|
||||||
echo.SetRange( 0, 100 );
|
echo.SetRange( 0, 100 );
|
||||||
echo.SetPos( (int)( m_echo * 100.0f ) );
|
echo.SetPos( (int)( m_echo * 100.0f ) );
|
||||||
|
|
||||||
stereo.SetRange( 0, 100 );
|
stereo.SetRange( 0, 100 );
|
||||||
stereo.SetPos( (int)( m_stereo * 100.0f ) );
|
stereo.SetPos( (int)( m_stereo * 100.0f ) );
|
||||||
|
|
||||||
sound_filtering.SetRange( 0, 100 );
|
sound_filtering.SetRange( 0, 100 );
|
||||||
sound_filtering.SetPos( (int)( m_sound_filtering * 100.0f ) );
|
sound_filtering.SetPos( (int)( m_sound_filtering * 100.0f ) );
|
||||||
|
|
||||||
volume.SetRange( (int)( MIN_VOLUME * 100.0f ), (int)( MAX_VOLUME * 100.0f ) );
|
volume.SetRange( (int)( MIN_VOLUME * 100.0f ), (int)( MAX_VOLUME * 100.0f ) );
|
||||||
volume.SetPos( (int)( m_volume * 100.0f ) );
|
volume.SetPos( (int)( m_volume * 100.0f ) );
|
||||||
|
|
||||||
unsigned int rate = 44100;
|
unsigned int rate = 44100;
|
||||||
CString temp;
|
CString temp;
|
||||||
for( int i = 0 ; i <= 2 ; i++ ) {
|
for( int i = 0 ; i <= 2 ; i++ ) {
|
||||||
temp.Format( _T("%u Hz"), rate );
|
temp.Format( _T("%u Hz"), rate );
|
||||||
int id = sample_rate.AddString( temp.GetString() );
|
int id = sample_rate.AddString( temp.GetString() );
|
||||||
sample_rate.SetItemData( id, rate );
|
sample_rate.SetItemData( id, rate );
|
||||||
if( rate == m_sample_rate ) {
|
if( rate == m_sample_rate ) {
|
||||||
sample_rate.SetCurSel( id );
|
sample_rate.SetCurSel( id );
|
||||||
}
|
}
|
||||||
rate /= 2;
|
rate /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE; // return TRUE unless you set the focus to a control
|
return TRUE; // return TRUE unless you set the focus to a control
|
||||||
// EXCEPTION: OCX Property Pages should return FALSE
|
// EXCEPTION: OCX Property Pages should return FALSE
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL AudioCoreSettingsDlg::PreTranslateMessage(MSG* pMsg)
|
BOOL AudioCoreSettingsDlg::PreTranslateMessage(MSG* pMsg)
|
||||||
{
|
{
|
||||||
// Required for enabling ToolTips in a modal dialog box.
|
// Required for enabling ToolTips in a modal dialog box.
|
||||||
if( NULL != toolTip ) {
|
if( NULL != toolTip ) {
|
||||||
toolTip->RelayEvent( pMsg );
|
toolTip->RelayEvent( pMsg );
|
||||||
}
|
}
|
||||||
|
|
||||||
return CDialog::PreTranslateMessage(pMsg);
|
return CDialog::PreTranslateMessage(pMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioCoreSettingsDlg::OnBnClickedDefaultVolume()
|
void AudioCoreSettingsDlg::OnBnClickedDefaultVolume()
|
||||||
{
|
{
|
||||||
volume.SetPos( 100 );
|
volume.SetPos( 100 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,47 +1,47 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// AudioCoreSettingsDlg dialog
|
// AudioCoreSettingsDlg dialog
|
||||||
|
|
||||||
class AudioCoreSettingsDlg : public CDialog
|
class AudioCoreSettingsDlg : public CDialog
|
||||||
{
|
{
|
||||||
DECLARE_DYNAMIC(AudioCoreSettingsDlg)
|
DECLARE_DYNAMIC(AudioCoreSettingsDlg)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool m_enabled;
|
bool m_enabled;
|
||||||
bool m_surround;
|
bool m_surround;
|
||||||
bool m_declicking;
|
bool m_declicking;
|
||||||
bool m_sound_interpolation;
|
bool m_sound_interpolation;
|
||||||
float m_echo;
|
float m_echo;
|
||||||
float m_stereo;
|
float m_stereo;
|
||||||
float m_volume;
|
float m_volume;
|
||||||
float m_sound_filtering;
|
float m_sound_filtering;
|
||||||
unsigned int m_sample_rate;
|
unsigned int m_sample_rate;
|
||||||
|
|
||||||
AudioCoreSettingsDlg(CWnd* pParent = NULL); // standard constructor
|
AudioCoreSettingsDlg(CWnd* pParent = NULL); // standard constructor
|
||||||
virtual ~AudioCoreSettingsDlg();
|
virtual ~AudioCoreSettingsDlg();
|
||||||
|
|
||||||
virtual BOOL OnInitDialog();
|
virtual BOOL OnInitDialog();
|
||||||
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
||||||
afx_msg void OnBnClickedDefaultVolume();
|
afx_msg void OnBnClickedDefaultVolume();
|
||||||
|
|
||||||
// Dialog Data
|
// Dialog Data
|
||||||
enum { IDD = IDD_AUDIO_CORE_SETTINGS };
|
enum { IDD = IDD_AUDIO_CORE_SETTINGS };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||||
afx_msg BOOL OnTtnNeedText(UINT id, NMHDR *pNMHDR, LRESULT *pResult); // Retrieve text for ToolTip
|
afx_msg BOOL OnTtnNeedText(UINT id, NMHDR *pNMHDR, LRESULT *pResult); // Retrieve text for ToolTip
|
||||||
|
|
||||||
DECLARE_MESSAGE_MAP()
|
DECLARE_MESSAGE_MAP()
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CButton enhance_sound;
|
CButton enhance_sound;
|
||||||
CButton surround;
|
CButton surround;
|
||||||
CButton declicking;
|
CButton declicking;
|
||||||
CButton sound_interpolation;
|
CButton sound_interpolation;
|
||||||
CSliderCtrl echo;
|
CSliderCtrl echo;
|
||||||
CSliderCtrl stereo;
|
CSliderCtrl stereo;
|
||||||
CSliderCtrl volume;
|
CSliderCtrl volume;
|
||||||
CSliderCtrl sound_filtering;
|
CSliderCtrl sound_filtering;
|
||||||
CToolTipCtrl *toolTip;
|
CToolTipCtrl *toolTip;
|
||||||
CComboBox sample_rate;
|
CComboBox sample_rate;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,76 +1,76 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "vba.h"
|
#include "vba.h"
|
||||||
#include "JoybusOptions.h"
|
#include "JoybusOptions.h"
|
||||||
#include "../gba/GBALink.h"
|
#include "../gba/GBALink.h"
|
||||||
|
|
||||||
// JoybusOptions dialog
|
// JoybusOptions dialog
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC(JoybusOptions, CDialog)
|
IMPLEMENT_DYNAMIC(JoybusOptions, CDialog)
|
||||||
|
|
||||||
JoybusOptions::JoybusOptions(CWnd* pParent /*=NULL*/)
|
JoybusOptions::JoybusOptions(CWnd* pParent /*=NULL*/)
|
||||||
: CDialog(JoybusOptions::IDD, pParent)
|
: CDialog(JoybusOptions::IDD, pParent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
JoybusOptions::~JoybusOptions()
|
JoybusOptions::~JoybusOptions()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void JoybusOptions::DoDataExchange(CDataExchange* pDX)
|
void JoybusOptions::DoDataExchange(CDataExchange* pDX)
|
||||||
{
|
{
|
||||||
CDialog::DoDataExchange(pDX);
|
CDialog::DoDataExchange(pDX);
|
||||||
DDX_Control(pDX, IDC_JOYBUS_ENABLE, enable_check);
|
DDX_Control(pDX, IDC_JOYBUS_ENABLE, enable_check);
|
||||||
DDX_Control(pDX, IDC_JOYBUS_HOSTNAME, hostname);
|
DDX_Control(pDX, IDC_JOYBUS_HOSTNAME, hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
BEGIN_MESSAGE_MAP(JoybusOptions, CDialog)
|
BEGIN_MESSAGE_MAP(JoybusOptions, CDialog)
|
||||||
ON_BN_CLICKED(IDC_JOYBUS_ENABLE, &JoybusOptions::OnBnClickedJoybusEnable)
|
ON_BN_CLICKED(IDC_JOYBUS_ENABLE, &JoybusOptions::OnBnClickedJoybusEnable)
|
||||||
ON_BN_CLICKED(IDOK, &JoybusOptions::OnBnClickedOk)
|
ON_BN_CLICKED(IDOK, &JoybusOptions::OnBnClickedOk)
|
||||||
END_MESSAGE_MAP()
|
END_MESSAGE_MAP()
|
||||||
|
|
||||||
BOOL JoybusOptions::OnInitDialog()
|
BOOL JoybusOptions::OnInitDialog()
|
||||||
{
|
{
|
||||||
CDialog::OnInitDialog();
|
CDialog::OnInitDialog();
|
||||||
|
|
||||||
enable_check.SetCheck(gba_joybus_enabled ? BST_CHECKED : BST_UNCHECKED);
|
enable_check.SetCheck(gba_joybus_enabled ? BST_CHECKED : BST_UNCHECKED);
|
||||||
|
|
||||||
hostname.EnableWindow(enable_check.GetCheck() == BST_CHECKED);
|
hostname.EnableWindow(enable_check.GetCheck() == BST_CHECKED);
|
||||||
|
|
||||||
hostname.SetWindowText(joybusHostAddr.ToString().c_str());
|
hostname.SetWindowText(joybusHostAddr.ToString().c_str());
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JoybusOptions::OnBnClickedJoybusEnable()
|
void JoybusOptions::OnBnClickedJoybusEnable()
|
||||||
{
|
{
|
||||||
hostname.EnableWindow(enable_check.GetCheck() == BST_CHECKED);
|
hostname.EnableWindow(enable_check.GetCheck() == BST_CHECKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JoybusOptions::OnBnClickedOk()
|
void JoybusOptions::OnBnClickedOk()
|
||||||
{
|
{
|
||||||
if ( (hostname.GetWindowTextLength() == 0)
|
if ( (hostname.GetWindowTextLength() == 0)
|
||||||
&& (enable_check.GetCheck() == BST_CHECKED) )
|
&& (enable_check.GetCheck() == BST_CHECKED) )
|
||||||
{
|
{
|
||||||
hostname.SetWindowText("Enter IP or Hostname");
|
hostname.SetWindowText("Enter IP or Hostname");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gba_joybus_enabled = enable_check.GetCheck() == BST_CHECKED;
|
gba_joybus_enabled = enable_check.GetCheck() == BST_CHECKED;
|
||||||
|
|
||||||
CString address;
|
CString address;
|
||||||
hostname.GetWindowText(address);
|
hostname.GetWindowText(address);
|
||||||
|
|
||||||
sf::IPAddress new_server;
|
sf::IPAddress new_server;
|
||||||
new_server = std::string(address);
|
new_server = std::string(address);
|
||||||
|
|
||||||
if (!new_server.IsValid())
|
if (!new_server.IsValid())
|
||||||
{
|
{
|
||||||
hostname.SetWindowText("Enter IP or Hostname");
|
hostname.SetWindowText("Enter IP or Hostname");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
joybusHostAddr = new_server;
|
joybusHostAddr = new_server;
|
||||||
JoyBusConnect();
|
JoyBusConnect();
|
||||||
|
|
||||||
OnOK();
|
OnOK();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "afxwin.h"
|
#include "afxwin.h"
|
||||||
|
|
||||||
// JoybusOptions dialog
|
// JoybusOptions dialog
|
||||||
|
|
||||||
class JoybusOptions : public CDialog
|
class JoybusOptions : public CDialog
|
||||||
{
|
{
|
||||||
DECLARE_DYNAMIC(JoybusOptions)
|
DECLARE_DYNAMIC(JoybusOptions)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JoybusOptions(CWnd* pParent = NULL); // standard constructor
|
JoybusOptions(CWnd* pParent = NULL); // standard constructor
|
||||||
virtual ~JoybusOptions();
|
virtual ~JoybusOptions();
|
||||||
|
|
||||||
// Dialog Data
|
// Dialog Data
|
||||||
enum { IDD = IDD_JOYBUS_DIALOG };
|
enum { IDD = IDD_JOYBUS_DIALOG };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||||
|
|
||||||
DECLARE_MESSAGE_MAP()
|
DECLARE_MESSAGE_MAP()
|
||||||
public:
|
public:
|
||||||
virtual BOOL OnInitDialog();
|
virtual BOOL OnInitDialog();
|
||||||
afx_msg void OnBnClickedJoybusEnable();
|
afx_msg void OnBnClickedJoybusEnable();
|
||||||
CButton enable_check;
|
CButton enable_check;
|
||||||
CEdit hostname;
|
CEdit hostname;
|
||||||
afx_msg void OnBnClickedOk();
|
afx_msg void OnBnClickedOk();
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,384 +1,384 @@
|
||||||
#ifndef NO_XAUDIO2
|
#ifndef NO_XAUDIO2
|
||||||
|
|
||||||
// MFC
|
// MFC
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
// Application
|
// Application
|
||||||
#include "VBA.h"
|
#include "VBA.h"
|
||||||
|
|
||||||
// Interface
|
// Interface
|
||||||
#include "../common/SoundDriver.h"
|
#include "../common/SoundDriver.h"
|
||||||
|
|
||||||
// XAudio2
|
// XAudio2
|
||||||
#include <xaudio2.h>
|
#include <xaudio2.h>
|
||||||
|
|
||||||
// Internals
|
// Internals
|
||||||
#include "../System.h" // for systemMessage()
|
#include "../System.h" // for systemMessage()
|
||||||
#include "../gba/Globals.h"
|
#include "../gba/Globals.h"
|
||||||
|
|
||||||
|
|
||||||
// Synchronization Event
|
// Synchronization Event
|
||||||
class XAudio2_BufferNotify : public IXAudio2VoiceCallback
|
class XAudio2_BufferNotify : public IXAudio2VoiceCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HANDLE hBufferEndEvent;
|
HANDLE hBufferEndEvent;
|
||||||
|
|
||||||
XAudio2_BufferNotify() {
|
XAudio2_BufferNotify() {
|
||||||
hBufferEndEvent = NULL;
|
hBufferEndEvent = NULL;
|
||||||
hBufferEndEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
hBufferEndEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
||||||
ASSERT( hBufferEndEvent != NULL );
|
ASSERT( hBufferEndEvent != NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
~XAudio2_BufferNotify() {
|
~XAudio2_BufferNotify() {
|
||||||
CloseHandle( hBufferEndEvent );
|
CloseHandle( hBufferEndEvent );
|
||||||
hBufferEndEvent = NULL;
|
hBufferEndEvent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHOD_( void, OnBufferEnd ) ( void *pBufferContext ) {
|
STDMETHOD_( void, OnBufferEnd ) ( void *pBufferContext ) {
|
||||||
ASSERT( hBufferEndEvent != NULL );
|
ASSERT( hBufferEndEvent != NULL );
|
||||||
SetEvent( hBufferEndEvent );
|
SetEvent( hBufferEndEvent );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// dummies:
|
// dummies:
|
||||||
STDMETHOD_( void, OnVoiceProcessingPassStart ) ( UINT32 BytesRequired ) {}
|
STDMETHOD_( void, OnVoiceProcessingPassStart ) ( UINT32 BytesRequired ) {}
|
||||||
STDMETHOD_( void, OnVoiceProcessingPassEnd ) () {}
|
STDMETHOD_( void, OnVoiceProcessingPassEnd ) () {}
|
||||||
STDMETHOD_( void, OnStreamEnd ) () {}
|
STDMETHOD_( void, OnStreamEnd ) () {}
|
||||||
STDMETHOD_( void, OnBufferStart ) ( void *pBufferContext ) {}
|
STDMETHOD_( void, OnBufferStart ) ( void *pBufferContext ) {}
|
||||||
STDMETHOD_( void, OnLoopEnd ) ( void *pBufferContext ) {}
|
STDMETHOD_( void, OnLoopEnd ) ( void *pBufferContext ) {}
|
||||||
STDMETHOD_( void, OnVoiceError ) ( void *pBufferContext, HRESULT Error ) {};
|
STDMETHOD_( void, OnVoiceError ) ( void *pBufferContext, HRESULT Error ) {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Class Declaration
|
// Class Declaration
|
||||||
class XAudio2_Output
|
class XAudio2_Output
|
||||||
: public SoundDriver
|
: public SoundDriver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XAudio2_Output();
|
XAudio2_Output();
|
||||||
~XAudio2_Output();
|
~XAudio2_Output();
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
bool init(long sampleRate);
|
bool init(long sampleRate);
|
||||||
|
|
||||||
// Sound Data Feed
|
// Sound Data Feed
|
||||||
void write(u16 * finalWave, int length);
|
void write(u16 * finalWave, int length);
|
||||||
|
|
||||||
// Play Control
|
// Play Control
|
||||||
void pause();
|
void pause();
|
||||||
void resume();
|
void resume();
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
// Configuration Changes
|
// Configuration Changes
|
||||||
void setThrottle( unsigned short throttle );
|
void setThrottle( unsigned short throttle );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool failed;
|
bool failed;
|
||||||
bool initialized;
|
bool initialized;
|
||||||
bool playing;
|
bool playing;
|
||||||
UINT32 freq;
|
UINT32 freq;
|
||||||
UINT32 bufferCount;
|
UINT32 bufferCount;
|
||||||
BYTE *buffers;
|
BYTE *buffers;
|
||||||
int currentBuffer;
|
int currentBuffer;
|
||||||
int soundBufferLen;
|
int soundBufferLen;
|
||||||
|
|
||||||
IXAudio2 *xaud;
|
IXAudio2 *xaud;
|
||||||
IXAudio2MasteringVoice *mVoice; // listener
|
IXAudio2MasteringVoice *mVoice; // listener
|
||||||
IXAudio2SourceVoice *sVoice; // sound source
|
IXAudio2SourceVoice *sVoice; // sound source
|
||||||
XAUDIO2_BUFFER buf;
|
XAUDIO2_BUFFER buf;
|
||||||
XAUDIO2_VOICE_STATE vState;
|
XAUDIO2_VOICE_STATE vState;
|
||||||
XAudio2_BufferNotify notify; // buffer end notification
|
XAudio2_BufferNotify notify; // buffer end notification
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Class Implementation
|
// Class Implementation
|
||||||
XAudio2_Output::XAudio2_Output()
|
XAudio2_Output::XAudio2_Output()
|
||||||
{
|
{
|
||||||
failed = false;
|
failed = false;
|
||||||
initialized = false;
|
initialized = false;
|
||||||
playing = false;
|
playing = false;
|
||||||
freq = 0;
|
freq = 0;
|
||||||
bufferCount = theApp.xa2BufferCount;
|
bufferCount = theApp.xa2BufferCount;
|
||||||
buffers = NULL;
|
buffers = NULL;
|
||||||
currentBuffer = 0;
|
currentBuffer = 0;
|
||||||
|
|
||||||
xaud = NULL;
|
xaud = NULL;
|
||||||
mVoice = NULL;
|
mVoice = NULL;
|
||||||
sVoice = NULL;
|
sVoice = NULL;
|
||||||
ZeroMemory( &buf, sizeof( buf ) );
|
ZeroMemory( &buf, sizeof( buf ) );
|
||||||
ZeroMemory( &vState, sizeof( vState ) );
|
ZeroMemory( &vState, sizeof( vState ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
XAudio2_Output::~XAudio2_Output()
|
XAudio2_Output::~XAudio2_Output()
|
||||||
{
|
{
|
||||||
initialized = false;
|
initialized = false;
|
||||||
|
|
||||||
if( sVoice ) {
|
if( sVoice ) {
|
||||||
if( playing ) {
|
if( playing ) {
|
||||||
HRESULT hr = sVoice->Stop( 0 );
|
HRESULT hr = sVoice->Stop( 0 );
|
||||||
ASSERT( hr == S_OK );
|
ASSERT( hr == S_OK );
|
||||||
}
|
}
|
||||||
sVoice->DestroyVoice();
|
sVoice->DestroyVoice();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( buffers ) {
|
if( buffers ) {
|
||||||
free( buffers );
|
free( buffers );
|
||||||
buffers = NULL;
|
buffers = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( mVoice ) {
|
if( mVoice ) {
|
||||||
mVoice->DestroyVoice();
|
mVoice->DestroyVoice();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( xaud ) {
|
if( xaud ) {
|
||||||
xaud->Release();
|
xaud->Release();
|
||||||
xaud = NULL;
|
xaud = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool XAudio2_Output::init(long sampleRate)
|
bool XAudio2_Output::init(long sampleRate)
|
||||||
{
|
{
|
||||||
if( failed || initialized ) return false;
|
if( failed || initialized ) return false;
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
// Initialize XAudio2
|
// Initialize XAudio2
|
||||||
UINT32 flags = 0;
|
UINT32 flags = 0;
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
flags = XAUDIO2_DEBUG_ENGINE;
|
flags = XAUDIO2_DEBUG_ENGINE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
hr = XAudio2Create( &xaud, flags );
|
hr = XAudio2Create( &xaud, flags );
|
||||||
if( hr != S_OK ) {
|
if( hr != S_OK ) {
|
||||||
systemMessage( IDS_XAUDIO2_FAILURE, NULL );
|
systemMessage( IDS_XAUDIO2_FAILURE, NULL );
|
||||||
failed = true;
|
failed = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
freq = sampleRate;
|
freq = sampleRate;
|
||||||
|
|
||||||
// calculate the number of samples per frame first
|
// calculate the number of samples per frame first
|
||||||
// then multiply it with the size of a sample frame (16 bit * stereo)
|
// then multiply it with the size of a sample frame (16 bit * stereo)
|
||||||
soundBufferLen = ( freq / 60 ) * 4;
|
soundBufferLen = ( freq / 60 ) * 4;
|
||||||
|
|
||||||
// create own buffers to store sound data because it must not be
|
// create own buffers to store sound data because it must not be
|
||||||
// manipulated while the voice plays from it
|
// manipulated while the voice plays from it
|
||||||
buffers = (BYTE *)malloc( ( bufferCount + 1 ) * soundBufferLen );
|
buffers = (BYTE *)malloc( ( bufferCount + 1 ) * soundBufferLen );
|
||||||
// + 1 because we need one temporary buffer when all others are in use
|
// + 1 because we need one temporary buffer when all others are in use
|
||||||
|
|
||||||
WAVEFORMATEX wfx;
|
WAVEFORMATEX wfx;
|
||||||
ZeroMemory( &wfx, sizeof( wfx ) );
|
ZeroMemory( &wfx, sizeof( wfx ) );
|
||||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||||
wfx.nChannels = 2;
|
wfx.nChannels = 2;
|
||||||
wfx.nSamplesPerSec = freq;
|
wfx.nSamplesPerSec = freq;
|
||||||
wfx.wBitsPerSample = 16;
|
wfx.wBitsPerSample = 16;
|
||||||
wfx.nBlockAlign = wfx.nChannels * ( wfx.wBitsPerSample / 8 );
|
wfx.nBlockAlign = wfx.nChannels * ( wfx.wBitsPerSample / 8 );
|
||||||
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
|
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
|
||||||
|
|
||||||
|
|
||||||
// create sound receiver
|
// create sound receiver
|
||||||
hr = xaud->CreateMasteringVoice(
|
hr = xaud->CreateMasteringVoice(
|
||||||
&mVoice,
|
&mVoice,
|
||||||
XAUDIO2_DEFAULT_CHANNELS,
|
XAUDIO2_DEFAULT_CHANNELS,
|
||||||
XAUDIO2_DEFAULT_SAMPLERATE,
|
XAUDIO2_DEFAULT_SAMPLERATE,
|
||||||
0,
|
0,
|
||||||
theApp.xa2Device,
|
theApp.xa2Device,
|
||||||
NULL );
|
NULL );
|
||||||
if( hr != S_OK ) {
|
if( hr != S_OK ) {
|
||||||
systemMessage( IDS_XAUDIO2_CANNOT_CREATE_MASTERINGVOICE, NULL );
|
systemMessage( IDS_XAUDIO2_CANNOT_CREATE_MASTERINGVOICE, NULL );
|
||||||
failed = true;
|
failed = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// create sound emitter
|
// create sound emitter
|
||||||
hr = xaud->CreateSourceVoice( &sVoice, &wfx, 0, 4.0f, ¬ify );
|
hr = xaud->CreateSourceVoice( &sVoice, &wfx, 0, 4.0f, ¬ify );
|
||||||
if( hr != S_OK ) {
|
if( hr != S_OK ) {
|
||||||
systemMessage( IDS_XAUDIO2_CANNOT_CREATE_SOURCEVOICE, NULL );
|
systemMessage( IDS_XAUDIO2_CANNOT_CREATE_SOURCEVOICE, NULL );
|
||||||
failed = true;
|
failed = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if( theApp.xa2Upmixing ) {
|
if( theApp.xa2Upmixing ) {
|
||||||
// set up stereo upmixing
|
// set up stereo upmixing
|
||||||
XAUDIO2_DEVICE_DETAILS dd;
|
XAUDIO2_DEVICE_DETAILS dd;
|
||||||
ZeroMemory( &dd, sizeof( dd ) );
|
ZeroMemory( &dd, sizeof( dd ) );
|
||||||
hr = xaud->GetDeviceDetails( 0, &dd );
|
hr = xaud->GetDeviceDetails( 0, &dd );
|
||||||
ASSERT( hr == S_OK );
|
ASSERT( hr == S_OK );
|
||||||
float *matrix = NULL;
|
float *matrix = NULL;
|
||||||
matrix = (float*)malloc( sizeof( float ) * 2 * dd.OutputFormat.Format.nChannels );
|
matrix = (float*)malloc( sizeof( float ) * 2 * dd.OutputFormat.Format.nChannels );
|
||||||
if( matrix == NULL ) return false;
|
if( matrix == NULL ) return false;
|
||||||
bool matrixAvailable = true;
|
bool matrixAvailable = true;
|
||||||
switch( dd.OutputFormat.Format.nChannels ) {
|
switch( dd.OutputFormat.Format.nChannels ) {
|
||||||
case 4: // 4.0
|
case 4: // 4.0
|
||||||
//Speaker \ Left Source Right Source
|
//Speaker \ Left Source Right Source
|
||||||
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
||||||
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
||||||
/*Back L*/ matrix[4] = 1.0000f; matrix[5] = 0.0000f;
|
/*Back L*/ matrix[4] = 1.0000f; matrix[5] = 0.0000f;
|
||||||
/*Back R*/ matrix[6] = 0.0000f; matrix[7] = 1.0000f;
|
/*Back R*/ matrix[6] = 0.0000f; matrix[7] = 1.0000f;
|
||||||
break;
|
break;
|
||||||
case 5: // 5.0
|
case 5: // 5.0
|
||||||
//Speaker \ Left Source Right Source
|
//Speaker \ Left Source Right Source
|
||||||
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
||||||
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
||||||
/*Front C*/ matrix[4] = 0.7071f; matrix[5] = 0.7071f;
|
/*Front C*/ matrix[4] = 0.7071f; matrix[5] = 0.7071f;
|
||||||
/*Side L*/ matrix[6] = 1.0000f; matrix[7] = 0.0000f;
|
/*Side L*/ matrix[6] = 1.0000f; matrix[7] = 0.0000f;
|
||||||
/*Side R*/ matrix[8] = 0.0000f; matrix[9] = 1.0000f;
|
/*Side R*/ matrix[8] = 0.0000f; matrix[9] = 1.0000f;
|
||||||
break;
|
break;
|
||||||
case 6: // 5.1
|
case 6: // 5.1
|
||||||
//Speaker \ Left Source Right Source
|
//Speaker \ Left Source Right Source
|
||||||
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
||||||
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
||||||
/*Front C*/ matrix[4] = 0.7071f; matrix[5] = 0.7071f;
|
/*Front C*/ matrix[4] = 0.7071f; matrix[5] = 0.7071f;
|
||||||
/*LFE */ matrix[6] = 0.0000f; matrix[7] = 0.0000f;
|
/*LFE */ matrix[6] = 0.0000f; matrix[7] = 0.0000f;
|
||||||
/*Side L*/ matrix[8] = 1.0000f; matrix[9] = 0.0000f;
|
/*Side L*/ matrix[8] = 1.0000f; matrix[9] = 0.0000f;
|
||||||
/*Side R*/ matrix[10] = 0.0000f; matrix[11] = 1.0000f;
|
/*Side R*/ matrix[10] = 0.0000f; matrix[11] = 1.0000f;
|
||||||
break;
|
break;
|
||||||
case 7: // 6.1
|
case 7: // 6.1
|
||||||
//Speaker \ Left Source Right Source
|
//Speaker \ Left Source Right Source
|
||||||
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
||||||
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
||||||
/*Front C*/ matrix[4] = 0.7071f; matrix[5] = 0.7071f;
|
/*Front C*/ matrix[4] = 0.7071f; matrix[5] = 0.7071f;
|
||||||
/*LFE */ matrix[6] = 0.0000f; matrix[7] = 0.0000f;
|
/*LFE */ matrix[6] = 0.0000f; matrix[7] = 0.0000f;
|
||||||
/*Side L*/ matrix[8] = 1.0000f; matrix[9] = 0.0000f;
|
/*Side L*/ matrix[8] = 1.0000f; matrix[9] = 0.0000f;
|
||||||
/*Side R*/ matrix[10] = 0.0000f; matrix[11] = 1.0000f;
|
/*Side R*/ matrix[10] = 0.0000f; matrix[11] = 1.0000f;
|
||||||
/*Back C*/ matrix[12] = 0.7071f; matrix[13] = 0.7071f;
|
/*Back C*/ matrix[12] = 0.7071f; matrix[13] = 0.7071f;
|
||||||
break;
|
break;
|
||||||
case 8: // 7.1
|
case 8: // 7.1
|
||||||
//Speaker \ Left Source Right Source
|
//Speaker \ Left Source Right Source
|
||||||
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
/*Front L*/ matrix[0] = 1.0000f; matrix[1] = 0.0000f;
|
||||||
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
/*Front R*/ matrix[2] = 0.0000f; matrix[3] = 1.0000f;
|
||||||
/*Front C*/ matrix[4] = 0.7071f; matrix[5] = 0.7071f;
|
/*Front C*/ matrix[4] = 0.7071f; matrix[5] = 0.7071f;
|
||||||
/*LFE */ matrix[6] = 0.0000f; matrix[7] = 0.0000f;
|
/*LFE */ matrix[6] = 0.0000f; matrix[7] = 0.0000f;
|
||||||
/*Back L*/ matrix[8] = 1.0000f; matrix[9] = 0.0000f;
|
/*Back L*/ matrix[8] = 1.0000f; matrix[9] = 0.0000f;
|
||||||
/*Back R*/ matrix[10] = 0.0000f; matrix[11] = 1.0000f;
|
/*Back R*/ matrix[10] = 0.0000f; matrix[11] = 1.0000f;
|
||||||
/*Side L*/ matrix[12] = 1.0000f; matrix[13] = 0.0000f;
|
/*Side L*/ matrix[12] = 1.0000f; matrix[13] = 0.0000f;
|
||||||
/*Side R*/ matrix[14] = 0.0000f; matrix[15] = 1.0000f;
|
/*Side R*/ matrix[14] = 0.0000f; matrix[15] = 1.0000f;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
matrixAvailable = false;
|
matrixAvailable = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( matrixAvailable ) {
|
if( matrixAvailable ) {
|
||||||
hr = sVoice->SetOutputMatrix( NULL, 2, dd.OutputFormat.Format.nChannels, matrix );
|
hr = sVoice->SetOutputMatrix( NULL, 2, dd.OutputFormat.Format.nChannels, matrix );
|
||||||
ASSERT( hr == S_OK );
|
ASSERT( hr == S_OK );
|
||||||
}
|
}
|
||||||
free( matrix );
|
free( matrix );
|
||||||
matrix = NULL;
|
matrix = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
hr = sVoice->Start( 0 );
|
hr = sVoice->Start( 0 );
|
||||||
ASSERT( hr == S_OK );
|
ASSERT( hr == S_OK );
|
||||||
playing = true;
|
playing = true;
|
||||||
|
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XAudio2_Output::write(u16 * finalWave, int length)
|
void XAudio2_Output::write(u16 * finalWave, int length)
|
||||||
{
|
{
|
||||||
if( !initialized || failed ) return;
|
if( !initialized || failed ) return;
|
||||||
|
|
||||||
while( true ) {
|
while( true ) {
|
||||||
sVoice->GetState( &vState );
|
sVoice->GetState( &vState );
|
||||||
|
|
||||||
ASSERT( vState.BuffersQueued <= bufferCount );
|
ASSERT( vState.BuffersQueued <= bufferCount );
|
||||||
|
|
||||||
if( vState.BuffersQueued < bufferCount ) {
|
if( vState.BuffersQueued < bufferCount ) {
|
||||||
if( vState.BuffersQueued == 0 ) {
|
if( vState.BuffersQueued == 0 ) {
|
||||||
// buffers ran dry
|
// buffers ran dry
|
||||||
if( systemVerbose & VERBOSE_SOUNDOUTPUT ) {
|
if( systemVerbose & VERBOSE_SOUNDOUTPUT ) {
|
||||||
static unsigned int i = 0;
|
static unsigned int i = 0;
|
||||||
log( "XAudio2: Buffers were not refilled fast enough (i=%i)\n", i++ );
|
log( "XAudio2: Buffers were not refilled fast enough (i=%i)\n", i++ );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// there is at least one free buffer
|
// there is at least one free buffer
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// the maximum number of buffers is currently queued
|
// the maximum number of buffers is currently queued
|
||||||
if( synchronize && !speedup && !theApp.throttle ) {
|
if( synchronize && !speedup && !theApp.throttle ) {
|
||||||
// wait for one buffer to finish playing
|
// wait for one buffer to finish playing
|
||||||
WaitForSingleObject( notify.hBufferEndEvent, INFINITE );
|
WaitForSingleObject( notify.hBufferEndEvent, INFINITE );
|
||||||
} else {
|
} else {
|
||||||
// drop current audio frame
|
// drop current audio frame
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy & protect the audio data in own memory area while playing it
|
// copy & protect the audio data in own memory area while playing it
|
||||||
CopyMemory( &buffers[ currentBuffer * soundBufferLen ], finalWave, soundBufferLen );
|
CopyMemory( &buffers[ currentBuffer * soundBufferLen ], finalWave, soundBufferLen );
|
||||||
|
|
||||||
buf.AudioBytes = soundBufferLen;
|
buf.AudioBytes = soundBufferLen;
|
||||||
buf.pAudioData = &buffers[ currentBuffer * soundBufferLen ];
|
buf.pAudioData = &buffers[ currentBuffer * soundBufferLen ];
|
||||||
|
|
||||||
currentBuffer++;
|
currentBuffer++;
|
||||||
currentBuffer %= ( bufferCount + 1 ); // + 1 because we need one temporary buffer
|
currentBuffer %= ( bufferCount + 1 ); // + 1 because we need one temporary buffer
|
||||||
|
|
||||||
HRESULT hr = sVoice->SubmitSourceBuffer( &buf ); // send buffer to queue
|
HRESULT hr = sVoice->SubmitSourceBuffer( &buf ); // send buffer to queue
|
||||||
ASSERT( hr == S_OK );
|
ASSERT( hr == S_OK );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XAudio2_Output::pause()
|
void XAudio2_Output::pause()
|
||||||
{
|
{
|
||||||
if( !initialized || failed ) return;
|
if( !initialized || failed ) return;
|
||||||
|
|
||||||
if( playing ) {
|
if( playing ) {
|
||||||
HRESULT hr = sVoice->Stop( 0 );
|
HRESULT hr = sVoice->Stop( 0 );
|
||||||
ASSERT( hr == S_OK );
|
ASSERT( hr == S_OK );
|
||||||
playing = false;
|
playing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XAudio2_Output::resume()
|
void XAudio2_Output::resume()
|
||||||
{
|
{
|
||||||
if( !initialized || failed ) return;
|
if( !initialized || failed ) return;
|
||||||
|
|
||||||
if( !playing ) {
|
if( !playing ) {
|
||||||
HRESULT hr = sVoice->Start( 0 );
|
HRESULT hr = sVoice->Start( 0 );
|
||||||
ASSERT( hr == S_OK );
|
ASSERT( hr == S_OK );
|
||||||
playing = true;
|
playing = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XAudio2_Output::reset()
|
void XAudio2_Output::reset()
|
||||||
{
|
{
|
||||||
if( !initialized || failed ) return;
|
if( !initialized || failed ) return;
|
||||||
|
|
||||||
if( playing ) {
|
if( playing ) {
|
||||||
HRESULT hr = sVoice->Stop( 0 );
|
HRESULT hr = sVoice->Stop( 0 );
|
||||||
ASSERT( hr == S_OK );
|
ASSERT( hr == S_OK );
|
||||||
}
|
}
|
||||||
|
|
||||||
sVoice->FlushSourceBuffers();
|
sVoice->FlushSourceBuffers();
|
||||||
sVoice->Start( 0 );
|
sVoice->Start( 0 );
|
||||||
playing = true;
|
playing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void XAudio2_Output::setThrottle( unsigned short throttle )
|
void XAudio2_Output::setThrottle( unsigned short throttle )
|
||||||
{
|
{
|
||||||
if( !initialized || failed ) return;
|
if( !initialized || failed ) return;
|
||||||
|
|
||||||
if( throttle == 0 ) throttle = 100;
|
if( throttle == 0 ) throttle = 100;
|
||||||
HRESULT hr = sVoice->SetFrequencyRatio( (float)throttle / 100.0f );
|
HRESULT hr = sVoice->SetFrequencyRatio( (float)throttle / 100.0f );
|
||||||
ASSERT( hr == S_OK );
|
ASSERT( hr == S_OK );
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundDriver *newXAudio2_Output()
|
SoundDriver *newXAudio2_Output()
|
||||||
{
|
{
|
||||||
return new XAudio2_Output();
|
return new XAudio2_Output();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // #ifndef NO_XAUDIO2
|
#endif // #ifndef NO_XAUDIO2
|
||||||
|
|
|
@ -1,151 +1,151 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#ifndef NO_XAUDIO2
|
#ifndef NO_XAUDIO2
|
||||||
#include "VBA.h"
|
#include "VBA.h"
|
||||||
|
|
||||||
#include "XAudio2_Config.h"
|
#include "XAudio2_Config.h"
|
||||||
|
|
||||||
#include <xaudio2.h>
|
#include <xaudio2.h>
|
||||||
|
|
||||||
|
|
||||||
// XAudio2_Config dialog
|
// XAudio2_Config dialog
|
||||||
|
|
||||||
IMPLEMENT_DYNAMIC(XAudio2_Config, CDialog)
|
IMPLEMENT_DYNAMIC(XAudio2_Config, CDialog)
|
||||||
|
|
||||||
XAudio2_Config::XAudio2_Config(CWnd* pParent /*=NULL*/)
|
XAudio2_Config::XAudio2_Config(CWnd* pParent /*=NULL*/)
|
||||||
: CDialog(XAudio2_Config::IDD, pParent)
|
: CDialog(XAudio2_Config::IDD, pParent)
|
||||||
, m_selected_device_index(0)
|
, m_selected_device_index(0)
|
||||||
, m_enable_upmixing(false)
|
, m_enable_upmixing(false)
|
||||||
, m_buffer_count(0)
|
, m_buffer_count(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
XAudio2_Config::~XAudio2_Config()
|
XAudio2_Config::~XAudio2_Config()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void XAudio2_Config::DoDataExchange(CDataExchange* pDX)
|
void XAudio2_Config::DoDataExchange(CDataExchange* pDX)
|
||||||
{
|
{
|
||||||
CDialog::DoDataExchange(pDX);
|
CDialog::DoDataExchange(pDX);
|
||||||
DDX_Control(pDX, IDC_COMBO_DEV, m_combo_dev);
|
DDX_Control(pDX, IDC_COMBO_DEV, m_combo_dev);
|
||||||
DDX_Control(pDX, IDC_SLIDER_BUFFER, m_slider_buffer);
|
DDX_Control(pDX, IDC_SLIDER_BUFFER, m_slider_buffer);
|
||||||
DDX_Control(pDX, IDC_INFO_BUFFER, m_info_buffer);
|
DDX_Control(pDX, IDC_INFO_BUFFER, m_info_buffer);
|
||||||
DDX_Control(pDX, IDC_CHECK_UPMIX, m_check_upmix);
|
DDX_Control(pDX, IDC_CHECK_UPMIX, m_check_upmix);
|
||||||
|
|
||||||
if( pDX->m_bSaveAndValidate == TRUE ) {
|
if( pDX->m_bSaveAndValidate == TRUE ) {
|
||||||
if( CB_ERR != m_combo_dev.GetCurSel() ) {
|
if( CB_ERR != m_combo_dev.GetCurSel() ) {
|
||||||
if( CB_ERR != m_combo_dev.GetItemData( m_combo_dev.GetCurSel() ) ) {
|
if( CB_ERR != m_combo_dev.GetItemData( m_combo_dev.GetCurSel() ) ) {
|
||||||
m_selected_device_index = m_combo_dev.GetItemData( m_combo_dev.GetCurSel() );
|
m_selected_device_index = m_combo_dev.GetItemData( m_combo_dev.GetCurSel() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_enable_upmixing = ( m_check_upmix.GetCheck() == BST_CHECKED );
|
m_enable_upmixing = ( m_check_upmix.GetCheck() == BST_CHECKED );
|
||||||
|
|
||||||
m_buffer_count = (UINT32)m_slider_buffer.GetPos();
|
m_buffer_count = (UINT32)m_slider_buffer.GetPos();
|
||||||
} else {
|
} else {
|
||||||
m_check_upmix.SetCheck( m_enable_upmixing ? BST_CHECKED : BST_UNCHECKED );
|
m_check_upmix.SetCheck( m_enable_upmixing ? BST_CHECKED : BST_UNCHECKED );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BEGIN_MESSAGE_MAP(XAudio2_Config, CDialog)
|
BEGIN_MESSAGE_MAP(XAudio2_Config, CDialog)
|
||||||
ON_WM_HSCROLL()
|
ON_WM_HSCROLL()
|
||||||
END_MESSAGE_MAP()
|
END_MESSAGE_MAP()
|
||||||
|
|
||||||
|
|
||||||
// XAudio2_Config message handlers
|
// XAudio2_Config message handlers
|
||||||
|
|
||||||
BOOL XAudio2_Config::OnInitDialog()
|
BOOL XAudio2_Config::OnInitDialog()
|
||||||
{
|
{
|
||||||
CDialog::OnInitDialog();
|
CDialog::OnInitDialog();
|
||||||
|
|
||||||
m_combo_dev.ResetContent();
|
m_combo_dev.ResetContent();
|
||||||
|
|
||||||
m_slider_buffer.SetRange( 2, 10, FALSE );
|
m_slider_buffer.SetRange( 2, 10, FALSE );
|
||||||
m_slider_buffer.SetTicFreq( 1 );
|
m_slider_buffer.SetTicFreq( 1 );
|
||||||
m_slider_buffer.SetPos( (int)m_buffer_count );
|
m_slider_buffer.SetPos( (int)m_buffer_count );
|
||||||
|
|
||||||
CString info;
|
CString info;
|
||||||
int pos = m_slider_buffer.GetPos();
|
int pos = m_slider_buffer.GetPos();
|
||||||
info.Format( _T("%i frames = %.2f ms"), pos, (float)pos / 60.0f * 1000.0f );
|
info.Format( _T("%i frames = %.2f ms"), pos, (float)pos / 60.0f * 1000.0f );
|
||||||
m_info_buffer.SetWindowText( info );
|
m_info_buffer.SetWindowText( info );
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
IXAudio2 *xa = NULL;
|
IXAudio2 *xa = NULL;
|
||||||
UINT32 flags = 0;
|
UINT32 flags = 0;
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
flags = XAUDIO2_DEBUG_ENGINE;
|
flags = XAUDIO2_DEBUG_ENGINE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
hr = XAudio2Create( &xa, flags );
|
hr = XAudio2Create( &xa, flags );
|
||||||
if( hr != S_OK ) {
|
if( hr != S_OK ) {
|
||||||
systemMessage( IDS_XAUDIO2_FAILURE, NULL );
|
systemMessage( IDS_XAUDIO2_FAILURE, NULL );
|
||||||
} else {
|
} else {
|
||||||
UINT32 dev_count = 0;
|
UINT32 dev_count = 0;
|
||||||
hr = xa->GetDeviceCount( &dev_count );
|
hr = xa->GetDeviceCount( &dev_count );
|
||||||
if( hr != S_OK ) {
|
if( hr != S_OK ) {
|
||||||
systemMessage( IDS_XAUDIO2_CANNOT_ENUMERATE_DEVICES, NULL );
|
systemMessage( IDS_XAUDIO2_CANNOT_ENUMERATE_DEVICES, NULL );
|
||||||
} else {
|
} else {
|
||||||
XAUDIO2_DEVICE_DETAILS dd;
|
XAUDIO2_DEVICE_DETAILS dd;
|
||||||
for( UINT32 i = 0; i < dev_count; i++ ) {
|
for( UINT32 i = 0; i < dev_count; i++ ) {
|
||||||
hr = xa->GetDeviceDetails( i, &dd );
|
hr = xa->GetDeviceDetails( i, &dd );
|
||||||
if( hr != S_OK ) {
|
if( hr != S_OK ) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
#ifdef _UNICODE
|
#ifdef _UNICODE
|
||||||
int id = m_combo_dev.AddString( dd.DisplayName );
|
int id = m_combo_dev.AddString( dd.DisplayName );
|
||||||
#else
|
#else
|
||||||
CHAR temp[256];
|
CHAR temp[256];
|
||||||
ZeroMemory( temp, sizeof( temp ) );
|
ZeroMemory( temp, sizeof( temp ) );
|
||||||
WideCharToMultiByte(
|
WideCharToMultiByte(
|
||||||
CP_ACP,
|
CP_ACP,
|
||||||
WC_NO_BEST_FIT_CHARS,
|
WC_NO_BEST_FIT_CHARS,
|
||||||
dd.DisplayName,
|
dd.DisplayName,
|
||||||
-1,
|
-1,
|
||||||
temp,
|
temp,
|
||||||
sizeof( temp ) - 1,
|
sizeof( temp ) - 1,
|
||||||
NULL,
|
NULL,
|
||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
int id = m_combo_dev.AddString( temp );
|
int id = m_combo_dev.AddString( temp );
|
||||||
#endif
|
#endif
|
||||||
if( id < 0 ) {
|
if( id < 0 ) {
|
||||||
systemMessage( IDS_XAUDIO2_CANNOT_ENUMERATE_DEVICES, NULL );
|
systemMessage( IDS_XAUDIO2_CANNOT_ENUMERATE_DEVICES, NULL );
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
m_combo_dev.SetItemData( id, i );
|
m_combo_dev.SetItemData( id, i );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// select the currently configured device {
|
// select the currently configured device {
|
||||||
int count = m_combo_dev.GetCount();
|
int count = m_combo_dev.GetCount();
|
||||||
if( count > 0 ) {
|
if( count > 0 ) {
|
||||||
for( int i = 0; i < count; i++ ) {
|
for( int i = 0; i < count; i++ ) {
|
||||||
if( m_combo_dev.GetItemData( i ) == m_selected_device_index ) {
|
if( m_combo_dev.GetItemData( i ) == m_selected_device_index ) {
|
||||||
m_combo_dev.SetCurSel( i );
|
m_combo_dev.SetCurSel( i );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
xa->Release();
|
xa->Release();
|
||||||
xa = NULL;
|
xa = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE; // return TRUE unless you set the focus to a control
|
return TRUE; // return TRUE unless you set the focus to a control
|
||||||
// EXCEPTION: OCX Property Pages should return FALSE
|
// EXCEPTION: OCX Property Pages should return FALSE
|
||||||
}
|
}
|
||||||
|
|
||||||
void XAudio2_Config::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
void XAudio2_Config::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
||||||
{
|
{
|
||||||
CString info;
|
CString info;
|
||||||
int pos = m_slider_buffer.GetPos();
|
int pos = m_slider_buffer.GetPos();
|
||||||
info.Format( _T("%i frames = %.2f ms"), pos, (float)pos / 60.0f * 1000.0f );
|
info.Format( _T("%i frames = %.2f ms"), pos, (float)pos / 60.0f * 1000.0f );
|
||||||
m_info_buffer.SetWindowText( info );
|
m_info_buffer.SetWindowText( info );
|
||||||
|
|
||||||
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
|
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,37 +1,37 @@
|
||||||
#ifndef NO_XAUDIO2
|
#ifndef NO_XAUDIO2
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
class XAudio2_Config : public CDialog
|
class XAudio2_Config : public CDialog
|
||||||
{
|
{
|
||||||
DECLARE_DYNAMIC(XAudio2_Config)
|
DECLARE_DYNAMIC(XAudio2_Config)
|
||||||
DECLARE_MESSAGE_MAP()
|
DECLARE_MESSAGE_MAP()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UINT32 m_selected_device_index;
|
UINT32 m_selected_device_index;
|
||||||
UINT32 m_buffer_count;
|
UINT32 m_buffer_count;
|
||||||
bool m_enable_upmixing;
|
bool m_enable_upmixing;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CComboBox m_combo_dev;
|
CComboBox m_combo_dev;
|
||||||
CSliderCtrl m_slider_buffer;
|
CSliderCtrl m_slider_buffer;
|
||||||
CStatic m_info_buffer;
|
CStatic m_info_buffer;
|
||||||
CButton m_check_upmix;
|
CButton m_check_upmix;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
XAudio2_Config(CWnd* pParent = NULL); // standard constructor
|
XAudio2_Config(CWnd* pParent = NULL); // standard constructor
|
||||||
virtual ~XAudio2_Config();
|
virtual ~XAudio2_Config();
|
||||||
|
|
||||||
// Dialog Data
|
// Dialog Data
|
||||||
enum { IDD = IDD_XAUDIO2_CONFIG };
|
enum { IDD = IDD_XAUDIO2_CONFIG };
|
||||||
|
|
||||||
virtual BOOL OnInitDialog();
|
virtual BOOL OnInitDialog();
|
||||||
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
|
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// The following macros define the minimum required platform. The minimum required platform
|
// The following macros define the minimum required platform. The minimum required platform
|
||||||
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
|
// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
|
||||||
// your application. The macros work by enabling all features available on platform versions up to and
|
// your application. The macros work by enabling all features available on platform versions up to and
|
||||||
// including the version specified.
|
// including the version specified.
|
||||||
|
|
||||||
// Modify the following defines if you have to target a platform prior to the ones specified below.
|
// Modify the following defines if you have to target a platform prior to the ones specified below.
|
||||||
// Refer to MSDN for the latest info on corresponding values for different platforms.
|
// Refer to MSDN for the latest info on corresponding values for different platforms.
|
||||||
#ifndef WINVER // Specifies that the minimum required platform is Windows 2000.
|
#ifndef WINVER // Specifies that the minimum required platform is Windows 2000.
|
||||||
#define WINVER 0x0500 // Change this to the appropriate value to target other versions of Windows.
|
#define WINVER 0x0500 // Change this to the appropriate value to target other versions of Windows.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows 2000.
|
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows 2000.
|
||||||
#define _WIN32_WINNT 0x0500 // Change this to the appropriate value to target other versions of Windows.
|
#define _WIN32_WINNT 0x0500 // Change this to the appropriate value to target other versions of Windows.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98.
|
#ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98.
|
||||||
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
|
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 5.0.
|
#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 5.0.
|
||||||
#define _WIN32_IE 0x0500 // Change this to the appropriate value to target other versions of IE.
|
#define _WIN32_IE 0x0500 // Change this to the appropriate value to target other versions of IE.
|
||||||
#endif // Actually, we don't care
|
#endif // Actually, we don't care
|
||||||
|
|
Loading…
Reference in New Issue