📄 7zin.c
字号:
{
UInt32 c2;
if (value >= 0xDC00)
return SZE_ARCHIVE_ERROR;
if (pos + 2 > sd->Size)
return SZE_ARCHIVE_ERROR;
c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
pos += 2;
if (c2 < 0xDC00 || c2 >= 0xE000)
return SZE_ARCHIVE_ERROR;
value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
}
for (numAdds = 1; numAdds < 5; numAdds++)
if (value < (((UInt32)1) << (numAdds * 5 + 6)))
break;
len += numAdds;
}
MY_ALLOC(char, file->Name, (size_t)len, allocFunc);
len = 0;
while(2 <= sd->Size)
{
int numAdds;
UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
SzSkeepDataSize(sd, 2);
if (value < 0x80)
{
file->Name[len++] = (char)value;
if (value == 0)
break;
continue;
}
if (value >= 0xD800 && value < 0xE000)
{
UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
SzSkeepDataSize(sd, 2);
value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
}
for (numAdds = 1; numAdds < 5; numAdds++)
if (value < (((UInt32)1) << (numAdds * 5 + 6)))
break;
file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
do
{
numAdds--;
file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
}
while(numAdds > 0);
len += numAdds;
}
}
return SZ_OK;
}
SZ_RESULT SzReadHeader2(
CSzData *sd,
CArchiveDatabaseEx *db, /* allocMain */
CFileSize **unPackSizes, /* allocTemp */
Byte **digestsDefined, /* allocTemp */
UInt32 **digests, /* allocTemp */
Byte **emptyStreamVector, /* allocTemp */
Byte **emptyFileVector, /* allocTemp */
Byte **lwtVector, /* allocTemp */
ISzAlloc *allocMain,
ISzAlloc *allocTemp)
{
UInt64 type;
UInt32 numUnPackStreams = 0;
UInt32 numFiles = 0;
CFileItem *files = 0;
UInt32 numEmptyStreams = 0;
UInt32 i;
RINOK(SzReadID(sd, &type));
if (type == k7zIdArchiveProperties)
{
RINOK(SzReadArchiveProperties(sd));
RINOK(SzReadID(sd, &type));
}
if (type == k7zIdMainStreamsInfo)
{
RINOK(SzReadStreamsInfo(sd,
&db->ArchiveInfo.DataStartPosition,
&db->Database,
&numUnPackStreams,
unPackSizes,
digestsDefined,
digests, allocMain->Alloc, allocTemp));
db->ArchiveInfo.DataStartPosition += db->ArchiveInfo.StartPositionAfterHeader;
RINOK(SzReadID(sd, &type));
}
if (type == k7zIdEnd)
return SZ_OK;
if (type != k7zIdFilesInfo)
return SZE_ARCHIVE_ERROR;
RINOK(SzReadNumber32(sd, &numFiles));
db->Database.NumFiles = numFiles;
MY_ALLOC(CFileItem, files, (size_t)numFiles, allocMain->Alloc);
db->Database.Files = files;
for(i = 0; i < numFiles; i++)
SzFileInit(files + i);
for (;;)
{
UInt64 type;
UInt64 size;
RINOK(SzReadID(sd, &type));
if (type == k7zIdEnd)
break;
RINOK(SzReadNumber(sd, &size));
if ((UInt64)(int)type != type)
{
RINOK(SzSkeepDataSize(sd, size));
}
else
switch((int)type)
{
case k7zIdName:
{
RINOK(SzReadSwitch(sd));
RINOK(SzReadFileNames(sd, numFiles, files, allocMain->Alloc))
break;
}
case k7zIdEmptyStream:
{
RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp->Alloc));
numEmptyStreams = 0;
for (i = 0; i < numFiles; i++)
if ((*emptyStreamVector)[i])
numEmptyStreams++;
break;
}
case k7zIdEmptyFile:
{
RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp->Alloc));
break;
}
case k7zIdLastWriteTime:
{
RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp->Alloc));
RINOK(SzReadSwitch(sd));
for (i = 0; i < numFiles; i++)
{
CFileItem *f = &files[i];
Byte defined = (*lwtVector)[i];
f->IsLastWriteTimeDefined = defined;
f->LastWriteTime.Low = f->LastWriteTime.High = 0;
if (defined)
{
RINOK(SzReadUInt32(sd, &f->LastWriteTime.Low));
RINOK(SzReadUInt32(sd, &f->LastWriteTime.High));
}
}
break;
}
default:
{
RINOK(SzSkeepDataSize(sd, size));
}
}
}
{
UInt32 emptyFileIndex = 0;
UInt32 sizeIndex = 0;
for(i = 0; i < numFiles; i++)
{
CFileItem *file = files + i;
file->IsAnti = 0;
if (*emptyStreamVector == 0)
file->HasStream = 1;
else
file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
if(file->HasStream)
{
file->IsDirectory = 0;
file->Size = (*unPackSizes)[sizeIndex];
file->FileCRC = (*digests)[sizeIndex];
file->IsFileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
sizeIndex++;
}
else
{
if (*emptyFileVector == 0)
file->IsDirectory = 1;
else
file->IsDirectory = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
emptyFileIndex++;
file->Size = 0;
file->IsFileCRCDefined = 0;
}
}
}
return SzArDbExFill(db, allocMain->Alloc);
}
SZ_RESULT SzReadHeader(
CSzData *sd,
CArchiveDatabaseEx *db,
ISzAlloc *allocMain,
ISzAlloc *allocTemp)
{
CFileSize *unPackSizes = 0;
Byte *digestsDefined = 0;
UInt32 *digests = 0;
Byte *emptyStreamVector = 0;
Byte *emptyFileVector = 0;
Byte *lwtVector = 0;
SZ_RESULT res = SzReadHeader2(sd, db,
&unPackSizes, &digestsDefined, &digests,
&emptyStreamVector, &emptyFileVector, &lwtVector,
allocMain, allocTemp);
allocTemp->Free(unPackSizes);
allocTemp->Free(digestsDefined);
allocTemp->Free(digests);
allocTemp->Free(emptyStreamVector);
allocTemp->Free(emptyFileVector);
allocTemp->Free(lwtVector);
return res;
}
SZ_RESULT SzReadAndDecodePackedStreams2(
ISzInStream *inStream,
CSzData *sd,
CSzByteBuffer *outBuffer,
CFileSize baseOffset,
CArchiveDatabase *db,
CFileSize **unPackSizes,
Byte **digestsDefined,
UInt32 **digests,
#ifndef _LZMA_IN_CB
Byte **inBuffer,
#endif
ISzAlloc *allocTemp)
{
UInt32 numUnPackStreams = 0;
CFileSize dataStartPos;
CFolder *folder;
#ifndef _LZMA_IN_CB
CFileSize packSize = 0;
UInt32 i = 0;
#endif
CFileSize unPackSize;
SZ_RESULT res;
RINOK(SzReadStreamsInfo(sd, &dataStartPos, db,
&numUnPackStreams, unPackSizes, digestsDefined, digests,
allocTemp->Alloc, allocTemp));
dataStartPos += baseOffset;
if (db->NumFolders != 1)
return SZE_ARCHIVE_ERROR;
folder = db->Folders;
unPackSize = SzFolderGetUnPackSize(folder);
RINOK(inStream->Seek(inStream, dataStartPos));
#ifndef _LZMA_IN_CB
for (i = 0; i < db->NumPackStreams; i++)
packSize += db->PackSizes[i];
MY_ALLOC(Byte, *inBuffer, (size_t)packSize, allocTemp->Alloc);
RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize));
#endif
if (!SzByteBufferCreate(outBuffer, (size_t)unPackSize, allocTemp->Alloc))
return SZE_OUTOFMEMORY;
res = SzDecode(db->PackSizes, folder,
#ifdef _LZMA_IN_CB
inStream, dataStartPos,
#else
*inBuffer,
#endif
outBuffer->Items, (size_t)unPackSize, allocTemp);
RINOK(res)
if (folder->UnPackCRCDefined)
if (CrcCalc(outBuffer->Items, (size_t)unPackSize) != folder->UnPackCRC)
return SZE_FAIL;
return SZ_OK;
}
SZ_RESULT SzReadAndDecodePackedStreams(
ISzInStream *inStream,
CSzData *sd,
CSzByteBuffer *outBuffer,
CFileSize baseOffset,
ISzAlloc *allocTemp)
{
CArchiveDatabase db;
CFileSize *unPackSizes = 0;
Byte *digestsDefined = 0;
UInt32 *digests = 0;
#ifndef _LZMA_IN_CB
Byte *inBuffer = 0;
#endif
SZ_RESULT res;
SzArchiveDatabaseInit(&db);
res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
&db, &unPackSizes, &digestsDefined, &digests,
#ifndef _LZMA_IN_CB
&inBuffer,
#endif
allocTemp);
SzArchiveDatabaseFree(&db, allocTemp->Free);
allocTemp->Free(unPackSizes);
allocTemp->Free(digestsDefined);
allocTemp->Free(digests);
#ifndef _LZMA_IN_CB
allocTemp->Free(inBuffer);
#endif
return res;
}
SZ_RESULT SzArchiveOpen2(
ISzInStream *inStream,
CArchiveDatabaseEx *db,
ISzAlloc *allocMain,
ISzAlloc *allocTemp)
{
Byte signature[k7zSignatureSize];
Byte version;
UInt32 crcFromArchive;
UInt64 nextHeaderOffset;
UInt64 nextHeaderSize;
UInt32 nextHeaderCRC;
UInt32 crc = 0;
CFileSize pos = 0;
CSzByteBuffer buffer;
CSzData sd;
SZ_RESULT res;
RINOK(SafeReadDirect(inStream, signature, k7zSignatureSize));
if (!TestSignatureCandidate(signature))
return SZE_ARCHIVE_ERROR;
/*
db.Clear();
db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
*/
RINOK(SafeReadDirectByte(inStream, &version));
if (version != k7zMajorVersion)
return SZE_ARCHIVE_ERROR;
RINOK(SafeReadDirectByte(inStream, &version));
RINOK(SafeReadDirectUInt32(inStream, &crcFromArchive, &crc));
crc = CRC_INIT_VAL;
RINOK(SafeReadDirectUInt64(inStream, &nextHeaderOffset, &crc));
RINOK(SafeReadDirectUInt64(inStream, &nextHeaderSize, &crc));
RINOK(SafeReadDirectUInt32(inStream, &nextHeaderCRC, &crc));
pos = k7zStartHeaderSize;
db->ArchiveInfo.StartPositionAfterHeader = pos;
if (CRC_GET_DIGEST(crc) != crcFromArchive)
return SZE_ARCHIVE_ERROR;
if (nextHeaderSize == 0)
return SZ_OK;
RINOK(inStream->Seek(inStream, (CFileSize)(pos + nextHeaderOffset)));
if (!SzByteBufferCreate(&buffer, (size_t)nextHeaderSize, allocTemp->Alloc))
return SZE_OUTOFMEMORY;
res = SafeReadDirect(inStream, buffer.Items, (size_t)nextHeaderSize);
if (res == SZ_OK)
{
res = SZE_ARCHIVE_ERROR;
if (CrcCalc(buffer.Items, (UInt32)nextHeaderSize) == nextHeaderCRC)
{
for (;;)
{
UInt64 type;
sd.Data = buffer.Items;
sd.Size = buffer.Capacity;
res = SzReadID(&sd, &type);
if (res != SZ_OK)
break;
if (type == k7zIdHeader)
{
res = SzReadHeader(&sd, db, allocMain, allocTemp);
break;
}
if (type != k7zIdEncodedHeader)
{
res = SZE_ARCHIVE_ERROR;
break;
}
{
CSzByteBuffer outBuffer;
res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer,
db->ArchiveInfo.StartPositionAfterHeader,
allocTemp);
if (res != SZ_OK)
{
SzByteBufferFree(&outBuffer, allocTemp->Free);
break;
}
SzByteBufferFree(&buffer, allocTemp->Free);
buffer.Items = outBuffer.Items;
buffer.Capacity = outBuffer.Capacity;
}
}
}
}
SzByteBufferFree(&buffer, allocTemp->Free);
return res;
}
SZ_RESULT SzArchiveOpen(
ISzInStream *inStream,
CArchiveDatabaseEx *db,
ISzAlloc *allocMain,
ISzAlloc *allocTemp)
{
SZ_RESULT res = SzArchiveOpen2(inStream, db, allocMain, allocTemp);
if (res != SZ_OK)
SzArDbExFree(db, allocMain->Free);
return res;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -