📄 7zin.c
字号:
UInt32 **packCRCs, void * (*allocFunc)(size_t size)){ UInt32 i; RINOK(SzReadSize(sd, dataOffset)); RINOK(SzReadNumber32(sd, numPackStreams)); RINOK(SzWaitAttribute(sd, k7zIdSize)); MY_ALLOC(CFileSize, *packSizes, (size_t)*numPackStreams, allocFunc); for(i = 0; i < *numPackStreams; i++) { RINOK(SzReadSize(sd, (*packSizes) + i)); } while(1) { UInt64 type; RINOK(SzReadID(sd, &type)); if (type == k7zIdEnd) break; if (type == k7zIdCRC) { RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, allocFunc)); continue; } RINOK(SzSkeepData(sd)); } if (*packCRCsDefined == 0) { MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, allocFunc); MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, allocFunc); for(i = 0; i < *numPackStreams; i++) { (*packCRCsDefined)[i] = 0; (*packCRCs)[i] = 0; } } return SZ_OK;}SZ_RESULT SzReadSwitch(CSzData *sd){ Byte external; RINOK(SzReadByte(sd, &external)); return (external == 0) ? SZ_OK: SZE_ARCHIVE_ERROR;}SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(size_t size)){ UInt32 numCoders; UInt32 numBindPairs; UInt32 numPackedStreams; UInt32 i; UInt32 numInStreams = 0; UInt32 numOutStreams = 0; RINOK(SzReadNumber32(sd, &numCoders)); folder->NumCoders = numCoders; MY_ALLOC(CCoderInfo, folder->Coders, (size_t)numCoders, allocFunc); for (i = 0; i < numCoders; i++) SzCoderInfoInit(folder->Coders + i); for (i = 0; i < numCoders; i++) { Byte mainByte; CCoderInfo *coder = folder->Coders + i; { RINOK(SzReadByte(sd, &mainByte)); coder->MethodID.IDSize = (Byte)(mainByte & 0xF); RINOK(SzReadBytes(sd, coder->MethodID.ID, coder->MethodID.IDSize)); if ((mainByte & 0x10) != 0) { RINOK(SzReadNumber32(sd, &coder->NumInStreams)); RINOK(SzReadNumber32(sd, &coder->NumOutStreams)); } else { coder->NumInStreams = 1; coder->NumOutStreams = 1; } if ((mainByte & 0x20) != 0) { UInt64 propertiesSize = 0; RINOK(SzReadNumber(sd, &propertiesSize)); if (!SzByteBufferCreate(&coder->Properties, (size_t)propertiesSize, allocFunc)) return SZE_OUTOFMEMORY; RINOK(SzReadBytes(sd, coder->Properties.Items, (size_t)propertiesSize)); } } while ((mainByte & 0x80) != 0) { RINOK(SzReadByte(sd, &mainByte)); RINOK(SzSkeepDataSize(sd, (mainByte & 0xF))); if ((mainByte & 0x10) != 0) { UInt32 n; RINOK(SzReadNumber32(sd, &n)); RINOK(SzReadNumber32(sd, &n)); } if ((mainByte & 0x20) != 0) { UInt64 propertiesSize = 0; RINOK(SzReadNumber(sd, &propertiesSize)); RINOK(SzSkeepDataSize(sd, propertiesSize)); } } numInStreams += (UInt32)coder->NumInStreams; numOutStreams += (UInt32)coder->NumOutStreams; } numBindPairs = numOutStreams - 1; folder->NumBindPairs = numBindPairs; MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, allocFunc); for (i = 0; i < numBindPairs; i++) { CBindPair *bindPair = folder->BindPairs + i;; RINOK(SzReadNumber32(sd, &bindPair->InIndex)); RINOK(SzReadNumber32(sd, &bindPair->OutIndex)); } numPackedStreams = numInStreams - (UInt32)numBindPairs; folder->NumPackStreams = numPackedStreams; MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackedStreams, allocFunc); if (numPackedStreams == 1) { UInt32 j; UInt32 pi = 0; for (j = 0; j < numInStreams; j++) if (SzFolderFindBindPairForInStream(folder, j) < 0) { folder->PackStreams[pi++] = j; break; } } else for(i = 0; i < numPackedStreams; i++) { RINOK(SzReadNumber32(sd, folder->PackStreams + i)); } return SZ_OK;}SZ_RESULT SzReadUnPackInfo( CSzData *sd, UInt32 *numFolders, CFolder **folders, /* for allocFunc */ void * (*allocFunc)(size_t size), ISzAlloc *allocTemp){ UInt32 i; RINOK(SzWaitAttribute(sd, k7zIdFolder)); RINOK(SzReadNumber32(sd, numFolders)); { RINOK(SzReadSwitch(sd)); MY_ALLOC(CFolder, *folders, (size_t)*numFolders, allocFunc); for(i = 0; i < *numFolders; i++) SzFolderInit((*folders) + i); for(i = 0; i < *numFolders; i++) { RINOK(SzGetNextFolderItem(sd, (*folders) + i, allocFunc)); } } RINOK(SzWaitAttribute(sd, k7zIdCodersUnPackSize)); for(i = 0; i < *numFolders; i++) { UInt32 j; CFolder *folder = (*folders) + i; UInt32 numOutStreams = SzFolderGetNumOutStreams(folder); MY_ALLOC(CFileSize, folder->UnPackSizes, (size_t)numOutStreams, allocFunc); for(j = 0; j < numOutStreams; j++) { RINOK(SzReadSize(sd, folder->UnPackSizes + j)); } } while(1) { UInt64 type; RINOK(SzReadID(sd, &type)); if (type == k7zIdEnd) return SZ_OK; if (type == k7zIdCRC) { SZ_RESULT res; Byte *crcsDefined = 0; UInt32 *crcs = 0; res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp->Alloc); if (res == SZ_OK) { for(i = 0; i < *numFolders; i++) { CFolder *folder = (*folders) + i; folder->UnPackCRCDefined = crcsDefined[i]; folder->UnPackCRC = crcs[i]; } } allocTemp->Free(crcs); allocTemp->Free(crcsDefined); RINOK(res); continue; } RINOK(SzSkeepData(sd)); }}SZ_RESULT SzReadSubStreamsInfo( CSzData *sd, UInt32 numFolders, CFolder *folders, UInt32 *numUnPackStreams, CFileSize **unPackSizes, Byte **digestsDefined, UInt32 **digests, ISzAlloc *allocTemp){ UInt64 type = 0; UInt32 i; UInt32 si = 0; UInt32 numDigests = 0; for(i = 0; i < numFolders; i++) folders[i].NumUnPackStreams = 1; *numUnPackStreams = numFolders; while(1) { RINOK(SzReadID(sd, &type)); if (type == k7zIdNumUnPackStream) { *numUnPackStreams = 0; for(i = 0; i < numFolders; i++) { UInt32 numStreams; RINOK(SzReadNumber32(sd, &numStreams)); folders[i].NumUnPackStreams = numStreams; *numUnPackStreams += numStreams; } continue; } if (type == k7zIdCRC || type == k7zIdSize) break; if (type == k7zIdEnd) break; RINOK(SzSkeepData(sd)); } if (*numUnPackStreams == 0) { *unPackSizes = 0; *digestsDefined = 0; *digests = 0; } else { *unPackSizes = (CFileSize *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(CFileSize)); RINOM(*unPackSizes); *digestsDefined = (Byte *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(Byte)); RINOM(*digestsDefined); *digests = (UInt32 *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(UInt32)); RINOM(*digests); } for(i = 0; i < numFolders; i++) { /* v3.13 incorrectly worked with empty folders v4.07: we check that folder is empty */ CFileSize sum = 0; UInt32 j; UInt32 numSubstreams = folders[i].NumUnPackStreams; if (numSubstreams == 0) continue; if (type == k7zIdSize) for (j = 1; j < numSubstreams; j++) { CFileSize size; RINOK(SzReadSize(sd, &size)); (*unPackSizes)[si++] = size; sum += size; } (*unPackSizes)[si++] = SzFolderGetUnPackSize(folders + i) - sum; } if (type == k7zIdSize) { RINOK(SzReadID(sd, &type)); } for(i = 0; i < *numUnPackStreams; i++) { (*digestsDefined)[i] = 0; (*digests)[i] = 0; } for(i = 0; i < numFolders; i++) { UInt32 numSubstreams = folders[i].NumUnPackStreams; if (numSubstreams != 1 || !folders[i].UnPackCRCDefined) numDigests += numSubstreams; } si = 0; while(1) { if (type == k7zIdCRC) { int digestIndex = 0; Byte *digestsDefined2 = 0; UInt32 *digests2 = 0; SZ_RESULT res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp->Alloc); if (res == SZ_OK) { for (i = 0; i < numFolders; i++) { CFolder *folder = folders + i; UInt32 numSubstreams = folder->NumUnPackStreams; if (numSubstreams == 1 && folder->UnPackCRCDefined) { (*digestsDefined)[si] = 1; (*digests)[si] = folder->UnPackCRC; si++; } else { UInt32 j; for (j = 0; j < numSubstreams; j++, digestIndex++) { (*digestsDefined)[si] = digestsDefined2[digestIndex]; (*digests)[si] = digests2[digestIndex]; si++; } } } } allocTemp->Free(digestsDefined2); allocTemp->Free(digests2); RINOK(res); } else if (type == k7zIdEnd) return SZ_OK; else { RINOK(SzSkeepData(sd)); } RINOK(SzReadID(sd, &type)); }}SZ_RESULT SzReadStreamsInfo( CSzData *sd, CFileSize *dataOffset, CArchiveDatabase *db, UInt32 *numUnPackStreams, CFileSize **unPackSizes, /* allocTemp */ Byte **digestsDefined, /* allocTemp */ UInt32 **digests, /* allocTemp */ void * (*allocFunc)(size_t size), ISzAlloc *allocTemp){ while(1) { UInt64 type; RINOK(SzReadID(sd, &type)); if ((UInt64)(int)type != type) return SZE_FAIL; switch((int)type) { case k7zIdEnd: return SZ_OK; case k7zIdPackInfo: { RINOK(SzReadPackInfo(sd, dataOffset, &db->NumPackStreams, &db->PackSizes, &db->PackCRCsDefined, &db->PackCRCs, allocFunc)); break; } case k7zIdUnPackInfo: { RINOK(SzReadUnPackInfo(sd, &db->NumFolders, &db->Folders, allocFunc, allocTemp)); break; } case k7zIdSubStreamsInfo: { RINOK(SzReadSubStreamsInfo(sd, db->NumFolders, db->Folders, numUnPackStreams, unPackSizes, digestsDefined, digests, allocTemp)); break; } default: return SZE_FAIL; } }}Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files, void * (*allocFunc)(size_t size)){ UInt32 i; for(i = 0; i < numFiles; i++) { UInt32 len = 0; UInt32 pos = 0; CFileItem *file = files + i; while(pos + 2 <= sd->Size) { int numAdds; UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8)); pos += 2; len++; if (value == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -