This commit is contained in:
Igor Pavlov
2015-06-15 00:00:00 +00:00
committed by Kornel Lesiński
parent 0713a3ab80
commit 54490d51d5
591 changed files with 34932 additions and 16390 deletions

View File

@@ -1,5 +1,5 @@
/* 7zMain.c - Test application for 7z Decoder
2015-01-02 : Igor Pavlov : Public domain */
2015-05-11 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -34,75 +34,117 @@ static int Buf_EnsureSize(CBuf *dest, size_t size)
}
#ifndef _WIN32
#define _USE_UTF8
#endif
static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
/* #define _USE_UTF8 */
static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen, const UInt16 *src, size_t srcLen)
#ifdef _USE_UTF8
#define _UTF8_START(n) (0x100 - (1 << (7 - (n))))
#define _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)))
static size_t Utf16_To_Utf8_Calc(const UInt16 *src, const UInt16 *srcLim)
{
size_t destPos = 0, srcPos = 0;
size_t size = 0;
for (;;)
{
unsigned numAdds;
UInt32 value;
if (srcPos == srcLen)
UInt32 val;
if (src == srcLim)
return size;
size++;
val = *src++;
if (val < 0x80)
continue;
if (val < _UTF8_RANGE(1))
{
*destLen = destPos;
return True;
}
value = src[srcPos++];
if (value < 0x80)
{
if (dest)
dest[destPos] = (char)value;
destPos++;
size++;
continue;
}
if (value >= 0xD800 && value < 0xE000)
if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
{
UInt32 c2;
if (value >= 0xDC00 || srcPos == srcLen)
break;
c2 = src[srcPos++];
if (c2 < 0xDC00 || c2 >= 0xE000)
break;
value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
UInt32 c2 = *src;
if (c2 >= 0xDC00 && c2 < 0xE000)
{
src++;
size += 3;
continue;
}
}
for (numAdds = 1; numAdds < 5; numAdds++)
if (value < (((UInt32)1) << (numAdds * 5 + 6)))
break;
if (dest)
dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
destPos++;
do
{
numAdds--;
if (dest)
dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
destPos++;
}
while (numAdds != 0);
size += 2;
}
}
static Byte *Utf16_To_Utf8(Byte *dest, const UInt16 *src, const UInt16 *srcLim)
{
for (;;)
{
UInt32 val;
if (src == srcLim)
return dest;
val = *src++;
if (val < 0x80)
{
*dest++ = (char)val;
continue;
}
if (val < _UTF8_RANGE(1))
{
dest[0] = _UTF8_HEAD(1, val);
dest[1] = _UTF8_CHAR(0, val);
dest += 2;
continue;
}
if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
{
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 += 4;
continue;
}
}
dest[0] = _UTF8_HEAD(2, val);
dest[1] = _UTF8_CHAR(1, val);
dest[2] = _UTF8_CHAR(0, val);
dest += 3;
}
*destLen = destPos;
return False;
}
static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen)
{
size_t destLen = 0;
Bool res;
Utf16_To_Utf8(NULL, &destLen, src, srcLen);
size_t destLen = Utf16_To_Utf8_Calc(src, src + srcLen);
destLen += 1;
if (!Buf_EnsureSize(dest, destLen))
return SZ_ERROR_MEM;
res = Utf16_To_Utf8(dest->data, &destLen, src, srcLen);
dest->data[destLen] = 0;
return res ? SZ_OK : SZ_ERROR_FAIL;
*Utf16_To_Utf8(dest->data, src, src + srcLen) = 0;
return SZ_OK;
}
#endif
static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
#ifdef _WIN32
#ifndef _USE_UTF8
, UINT codePage
#endif
)
@@ -110,7 +152,7 @@ static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
unsigned len = 0;
for (len = 0; s[len] != 0; len++);
#ifdef _WIN32
#ifndef _USE_UTF8
{
unsigned size = len * 3 + 100;
if (!Buf_EnsureSize(buf, size))
@@ -191,7 +233,7 @@ static SRes PrintString(const UInt16 *s)
SRes res;
Buf_Init(&buf);
res = Utf16_To_Char(&buf, s
#ifdef _WIN32
#ifndef _USE_UTF8
, CP_OEMCP
#endif
);
@@ -281,7 +323,7 @@ static void ConvertFileTimeToString(const CNtfsFileTime *nt, char *s)
UIntToStr_2(s, sec); s[2] = 0;
}
void PrintError(const char *sz)
void PrintError(char *sz)
{
printf("\nERROR: %s\n", sz);
}
@@ -318,6 +360,7 @@ int MY_CDECL main(int numargs, char *args[])
// UInt32 parents[NUM_PARENTS_MAX];
printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n");
if (numargs == 1)
{
printf(
@@ -329,6 +372,7 @@ int MY_CDECL main(int numargs, char *args[])
" x: eXtract files with full paths\n");
return 0;
}
if (numargs < 3)
{
PrintError("incorrect command");
@@ -364,11 +408,14 @@ int MY_CDECL main(int numargs, char *args[])
CrcGenerateTable();
SzArEx_Init(&db);
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
if (res == SZ_OK)
{
char *command = args[1];
int listCommand = 0, testCommand = 0, fullPaths = 0;
if (strcmp(command, "l") == 0) listCommand = 1;
else if (strcmp(command, "t") == 0) testCommand = 1;
else if (strcmp(command, "e") == 0) { }
@@ -397,7 +444,7 @@ int MY_CDECL main(int numargs, char *args[])
size_t outSizeProcessed = 0;
// const CSzFileItem *f = db.Files + i;
size_t len;
int isDir = SzArEx_IsDir(&db, i);
unsigned isDir = SzArEx_IsDir(&db, i);
if (listCommand == 0 && isDir && !fullPaths)
continue;
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
@@ -433,6 +480,7 @@ int MY_CDECL main(int numargs, char *args[])
fileSize = SzArEx_GetFileSize(&db, i);
UInt64ToStr(fileSize, s);
if (SzBitWithVals_Check(&db.MTime, i))
ConvertFileTimeToString(&db.MTime.Vals[i], t);
else
@@ -452,6 +500,7 @@ int MY_CDECL main(int numargs, char *args[])
printf("\n");
continue;
}
fputs(testCommand ?
"Testing ":
"Extracting ",
@@ -459,6 +508,7 @@ int MY_CDECL main(int numargs, char *args[])
res = PrintString(temp);
if (res != SZ_OK)
break;
if (isDir)
printf("/");
else
@@ -470,6 +520,7 @@ int MY_CDECL main(int numargs, char *args[])
if (res != SZ_OK)
break;
}
if (!testCommand)
{
CSzFile outFile;
@@ -477,6 +528,7 @@ int MY_CDECL main(int numargs, char *args[])
size_t j;
UInt16 *name = (UInt16 *)temp;
const UInt16 *destPath = (const UInt16 *)name;
for (j = 0; name[j] != 0; j++)
if (name[j] == '/')
{
@@ -502,19 +554,23 @@ int MY_CDECL main(int numargs, char *args[])
res = SZ_ERROR_FAIL;
break;
}
processedSize = outSizeProcessed;
if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
{
PrintError("can not write output file");
res = SZ_ERROR_FAIL;
break;
}
if (File_Close(&outFile))
{
PrintError("can not close output file");
res = SZ_ERROR_FAIL;
break;
}
#ifdef USE_WINDOWS_FILE
if (SzBitWithVals_Check(&db.Attribs, i))
SetFileAttributesW(destPath, db.Attribs.Vals[i]);
@@ -525,15 +581,18 @@ int MY_CDECL main(int numargs, char *args[])
IAlloc_Free(&allocImp, outBuffer);
}
}
SzArEx_Free(&db, &allocImp);
SzFree(NULL, temp);
File_Close(&archiveStream.file);
if (res == SZ_OK)
{
printf("\nEverything is Ok\n");
return 0;
}
if (res == SZ_ERROR_UNSUPPORTED)
PrintError("decoder doesn't support this archive");
else if (res == SZ_ERROR_MEM)
@@ -542,5 +601,6 @@ int MY_CDECL main(int numargs, char *args[])
PrintError("CRC error");
else
printf("\nERROR #%d\n", res);
return 1;
}