|
|
|
@@ -1,5 +1,5 @@
|
|
|
|
|
/* 7zMain.c - Test application for 7z Decoder
|
|
|
|
|
2021-04-29 : Igor Pavlov : Public domain */
|
|
|
|
|
2023-04-04 : Igor Pavlov : Public domain */
|
|
|
|
|
|
|
|
|
|
#include "Precomp.h"
|
|
|
|
|
|
|
|
|
@@ -32,10 +32,10 @@
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define kInputBufSize ((size_t)1 << 18)
|
|
|
|
|
|
|
|
|
|
static const ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
|
|
|
|
// static const ISzAlloc g_Alloc_temp = { SzAllocTemp, SzFreeTemp };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void Print(const char *s)
|
|
|
|
@@ -53,19 +53,19 @@ static int Buf_EnsureSize(CBuf *dest, size_t size)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef _WIN32
|
|
|
|
|
#define _USE_UTF8
|
|
|
|
|
#define MY_USE_UTF8
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* #define _USE_UTF8 */
|
|
|
|
|
/* #define MY_USE_UTF8 */
|
|
|
|
|
|
|
|
|
|
#ifdef _USE_UTF8
|
|
|
|
|
#ifdef MY_USE_UTF8
|
|
|
|
|
|
|
|
|
|
#define _UTF8_START(n) (0x100 - (1 << (7 - (n))))
|
|
|
|
|
#define MY_UTF8_START(n) (0x100 - (1 << (7 - (n))))
|
|
|
|
|
|
|
|
|
|
#define _UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6))
|
|
|
|
|
#define MY_UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6))
|
|
|
|
|
|
|
|
|
|
#define _UTF8_HEAD(n, val) ((Byte)(_UTF8_START(n) + (val >> (6 * (n)))))
|
|
|
|
|
#define _UTF8_CHAR(n, val) ((Byte)(0x80 + (((val) >> (6 * (n))) & 0x3F)))
|
|
|
|
|
#define MY_UTF8_HEAD(n, val) ((Byte)(MY_UTF8_START(n) + (val >> (6 * (n)))))
|
|
|
|
|
#define MY_UTF8_CHAR(n, val) ((Byte)(0x80 + (((val) >> (6 * (n))) & 0x3F)))
|
|
|
|
|
|
|
|
|
|
static size_t Utf16_To_Utf8_Calc(const UInt16 *src, const UInt16 *srcLim)
|
|
|
|
|
{
|
|
|
|
@@ -82,7 +82,7 @@ static size_t Utf16_To_Utf8_Calc(const UInt16 *src, const UInt16 *srcLim)
|
|
|
|
|
if (val < 0x80)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (val < _UTF8_RANGE(1))
|
|
|
|
|
if (val < MY_UTF8_RANGE(1))
|
|
|
|
|
{
|
|
|
|
|
size++;
|
|
|
|
|
continue;
|
|
|
|
@@ -90,7 +90,7 @@ static size_t Utf16_To_Utf8_Calc(const UInt16 *src, const UInt16 *srcLim)
|
|
|
|
|
|
|
|
|
|
if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
|
|
|
|
|
{
|
|
|
|
|
UInt32 c2 = *src;
|
|
|
|
|
const UInt32 c2 = *src;
|
|
|
|
|
if (c2 >= 0xDC00 && c2 < 0xE000)
|
|
|
|
|
{
|
|
|
|
|
src++;
|
|
|
|
@@ -119,33 +119,33 @@ static Byte *Utf16_To_Utf8(Byte *dest, const UInt16 *src, const UInt16 *srcLim)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (val < _UTF8_RANGE(1))
|
|
|
|
|
if (val < MY_UTF8_RANGE(1))
|
|
|
|
|
{
|
|
|
|
|
dest[0] = _UTF8_HEAD(1, val);
|
|
|
|
|
dest[1] = _UTF8_CHAR(0, val);
|
|
|
|
|
dest[0] = MY_UTF8_HEAD(1, val);
|
|
|
|
|
dest[1] = MY_UTF8_CHAR(0, val);
|
|
|
|
|
dest += 2;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
|
|
|
|
|
{
|
|
|
|
|
UInt32 c2 = *src;
|
|
|
|
|
const UInt32 c2 = *src;
|
|
|
|
|
if (c2 >= 0xDC00 && c2 < 0xE000)
|
|
|
|
|
{
|
|
|
|
|
src++;
|
|
|
|
|
val = (((val - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
|
|
|
|
|
dest[0] = _UTF8_HEAD(3, val);
|
|
|
|
|
dest[1] = _UTF8_CHAR(2, val);
|
|
|
|
|
dest[2] = _UTF8_CHAR(1, val);
|
|
|
|
|
dest[3] = _UTF8_CHAR(0, val);
|
|
|
|
|
dest[0] = MY_UTF8_HEAD(3, val);
|
|
|
|
|
dest[1] = MY_UTF8_CHAR(2, val);
|
|
|
|
|
dest[2] = MY_UTF8_CHAR(1, val);
|
|
|
|
|
dest[3] = MY_UTF8_CHAR(0, val);
|
|
|
|
|
dest += 4;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dest[0] = _UTF8_HEAD(2, val);
|
|
|
|
|
dest[1] = _UTF8_CHAR(1, val);
|
|
|
|
|
dest[2] = _UTF8_CHAR(0, val);
|
|
|
|
|
dest[0] = MY_UTF8_HEAD(2, val);
|
|
|
|
|
dest[1] = MY_UTF8_CHAR(1, val);
|
|
|
|
|
dest[2] = MY_UTF8_CHAR(0, val);
|
|
|
|
|
dest += 3;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -163,7 +163,7 @@ static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
|
|
|
|
|
#ifndef _USE_UTF8
|
|
|
|
|
#ifndef MY_USE_UTF8
|
|
|
|
|
, UINT codePage
|
|
|
|
|
#endif
|
|
|
|
|
)
|
|
|
|
@@ -171,7 +171,7 @@ static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
|
|
|
|
|
unsigned len = 0;
|
|
|
|
|
for (len = 0; s[len] != 0; len++) {}
|
|
|
|
|
|
|
|
|
|
#ifndef _USE_UTF8
|
|
|
|
|
#ifndef MY_USE_UTF8
|
|
|
|
|
{
|
|
|
|
|
const unsigned size = len * 3 + 100;
|
|
|
|
|
if (!Buf_EnsureSize(buf, size))
|
|
|
|
@@ -216,7 +216,7 @@ static WRes MyCreateDir(const UInt16 *name)
|
|
|
|
|
CBuf buf;
|
|
|
|
|
WRes res;
|
|
|
|
|
Buf_Init(&buf);
|
|
|
|
|
RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM));
|
|
|
|
|
RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM))
|
|
|
|
|
|
|
|
|
|
res =
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
@@ -239,7 +239,7 @@ static WRes OutFile_OpenUtf16(CSzFile *p, const UInt16 *name)
|
|
|
|
|
CBuf buf;
|
|
|
|
|
WRes res;
|
|
|
|
|
Buf_Init(&buf);
|
|
|
|
|
RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM));
|
|
|
|
|
RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM))
|
|
|
|
|
res = OutFile_Open(p, (const char *)buf.data);
|
|
|
|
|
Buf_Free(&buf, &g_Alloc);
|
|
|
|
|
return res;
|
|
|
|
@@ -253,7 +253,7 @@ static SRes PrintString(const UInt16 *s)
|
|
|
|
|
SRes res;
|
|
|
|
|
Buf_Init(&buf);
|
|
|
|
|
res = Utf16_To_Char(&buf, s
|
|
|
|
|
#ifndef _USE_UTF8
|
|
|
|
|
#ifndef MY_USE_UTF8
|
|
|
|
|
, CP_OEMCP
|
|
|
|
|
#endif
|
|
|
|
|
);
|
|
|
|
@@ -328,12 +328,12 @@ typedef struct _FILETIME
|
|
|
|
|
|
|
|
|
|
static LONG TIME_GetBias()
|
|
|
|
|
{
|
|
|
|
|
time_t utc = time(NULL);
|
|
|
|
|
const time_t utc = time(NULL);
|
|
|
|
|
struct tm *ptm = localtime(&utc);
|
|
|
|
|
int localdaylight = ptm->tm_isdst; /* daylight for local timezone */
|
|
|
|
|
const int localdaylight = ptm->tm_isdst; /* daylight for local timezone */
|
|
|
|
|
ptm = gmtime(&utc);
|
|
|
|
|
ptm->tm_isdst = localdaylight; /* use local daylight, not that of Greenwich */
|
|
|
|
|
LONG bias = (int)(mktime(ptm)-utc);
|
|
|
|
|
const LONG bias = (int)(mktime(ptm) - utc);
|
|
|
|
|
return bias;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -352,7 +352,7 @@ static BOOL WINAPI FileTimeToLocalFileTime(const FILETIME *fileTime, FILETIME *l
|
|
|
|
|
{
|
|
|
|
|
UInt64 v = GET_TIME_64(fileTime);
|
|
|
|
|
v = (UInt64)((Int64)v - (Int64)TIME_GetBias() * TICKS_PER_SEC);
|
|
|
|
|
SET_FILETIME(localFileTime, v);
|
|
|
|
|
SET_FILETIME(localFileTime, v)
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -364,7 +364,7 @@ static const UInt64 kUnixTimeOffset =
|
|
|
|
|
|
|
|
|
|
static Int64 Time_FileTimeToUnixTime64(const FILETIME *ft)
|
|
|
|
|
{
|
|
|
|
|
UInt64 winTime = GET_TIME_64(ft);
|
|
|
|
|
const UInt64 winTime = GET_TIME_64(ft);
|
|
|
|
|
return (Int64)(winTime / kNumTimeQuantumsInSecond) - (Int64)kUnixTimeOffset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -384,8 +384,8 @@ static void FILETIME_To_timespec(const FILETIME *ft, struct MY_ST_TIMESPEC *ts)
|
|
|
|
|
if (sec2 == sec)
|
|
|
|
|
{
|
|
|
|
|
ts->tv_sec = sec2;
|
|
|
|
|
UInt64 winTime = GET_TIME_64(ft);
|
|
|
|
|
ts->tv_nsec = (long)((winTime % 10000000) * 100);;
|
|
|
|
|
const UInt64 winTime = GET_TIME_64(ft);
|
|
|
|
|
ts->tv_nsec = (long)((winTime % 10000000) * 100);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -407,7 +407,7 @@ static WRes Set_File_FILETIME(const UInt16 *name, const FILETIME *mTime)
|
|
|
|
|
CBuf buf;
|
|
|
|
|
int res;
|
|
|
|
|
Buf_Init(&buf);
|
|
|
|
|
RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM));
|
|
|
|
|
RINOK(Utf16_To_Char(&buf, name MY_FILE_CODE_PAGE_PARAM))
|
|
|
|
|
FILETIME_To_timespec(NULL, ×[0]);
|
|
|
|
|
FILETIME_To_timespec(mTime, ×[1]);
|
|
|
|
|
res = utimensat(AT_FDCWD, (const char *)buf.data, times, flags);
|
|
|
|
@@ -461,7 +461,7 @@ static void ConvertFileTimeToString(const CNtfsFileTime *nTime, char *s)
|
|
|
|
|
ms[1] = 29;
|
|
|
|
|
for (mon = 0;; mon++)
|
|
|
|
|
{
|
|
|
|
|
unsigned d = ms[mon];
|
|
|
|
|
const unsigned d = ms[mon];
|
|
|
|
|
if (v < d)
|
|
|
|
|
break;
|
|
|
|
|
v -= d;
|
|
|
|
@@ -474,7 +474,7 @@ static void ConvertFileTimeToString(const CNtfsFileTime *nTime, char *s)
|
|
|
|
|
UIntToStr_2(s, sec); s[2] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void PrintLF()
|
|
|
|
|
static void PrintLF(void)
|
|
|
|
|
{
|
|
|
|
|
Print("\n");
|
|
|
|
|
}
|
|
|
|
@@ -541,7 +541,7 @@ static void GetAttribString(UInt32 wa, BoolInt isDir, char *s)
|
|
|
|
|
|
|
|
|
|
// #define NUM_PARENTS_MAX 128
|
|
|
|
|
|
|
|
|
|
int MY_CDECL main(int numargs, char *args[])
|
|
|
|
|
int Z7_CDECL main(int numargs, char *args[])
|
|
|
|
|
{
|
|
|
|
|
ISzAlloc allocImp;
|
|
|
|
|
ISzAlloc allocTempImp;
|
|
|
|
@@ -581,6 +581,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|
|
|
|
|
|
|
|
|
allocImp = g_Alloc;
|
|
|
|
|
allocTempImp = g_Alloc;
|
|
|
|
|
// allocTempImp = g_Alloc_temp;
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
WRes wres =
|
|
|
|
@@ -611,7 +612,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|
|
|
|
{
|
|
|
|
|
lookStream.bufSize = kInputBufSize;
|
|
|
|
|
lookStream.realStream = &archiveStream.vt;
|
|
|
|
|
LookToRead2_Init(&lookStream);
|
|
|
|
|
LookToRead2_INIT(&lookStream)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -767,7 +768,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
WRes wres = OutFile_OpenUtf16(&outFile, destPath);
|
|
|
|
|
const WRes wres = OutFile_OpenUtf16(&outFile, destPath);
|
|
|
|
|
if (wres != 0)
|
|
|
|
|
{
|
|
|
|
|
PrintError_WRes("cannot open output file", wres);
|
|
|
|
@@ -779,7 +780,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|
|
|
|
processedSize = outSizeProcessed;
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
WRes wres = File_Write(&outFile, outBuffer + offset, &processedSize);
|
|
|
|
|
const WRes wres = File_Write(&outFile, outBuffer + offset, &processedSize);
|
|
|
|
|
if (wres != 0 || processedSize != outSizeProcessed)
|
|
|
|
|
{
|
|
|
|
|
PrintError_WRes("cannot write output file", wres);
|
|
|
|
@@ -819,7 +820,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
WRes wres = File_Close(&outFile);
|
|
|
|
|
const WRes wres = File_Close(&outFile);
|
|
|
|
|
if (wres != 0)
|
|
|
|
|
{
|
|
|
|
|
PrintError_WRes("cannot close output file", wres);
|
|
|
|
|