5 #include "../../7zCrc.h"
9 CArchiveDatabaseEx *db,
13 size_t *outBufferSize,
15 size_t *outSizeProcessed,
19 UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex];
20 SZ_RESULT res = SZ_OK;
22 *outSizeProcessed = 0;
23 if (folderIndex == (UInt32)-1)
25 allocMain->Free(*outBuffer);
26 *blockIndex = folderIndex;
32 if (*outBuffer == 0 || *blockIndex != folderIndex)
34 CFolder *folder = db->Database.Folders + folderIndex;
35 CFileSize unPackSizeSpec = SzFolderGetUnPackSize(folder);
36 size_t unPackSize = (size_t)unPackSizeSpec;
37 CFileSize startOffset = SzArDbGetFolderStreamPos(db, folderIndex, 0);
41 CFileSize packSizeSpec;
43 RINOK(SzArDbGetFolderFullPackSize(db, folderIndex, &packSizeSpec));
44 packSize = (size_t)packSizeSpec;
45 if (packSize != packSizeSpec)
46 return SZE_OUTOFMEMORY;
48 if (unPackSize != unPackSizeSpec)
49 return SZE_OUTOFMEMORY;
50 *blockIndex = folderIndex;
51 allocMain->Free(*outBuffer);
54 RINOK(inStream->Seek(inStream, startOffset));
59 inBuffer = (Byte *)allocTemp->Alloc(packSize);
61 return SZE_OUTOFMEMORY;
63 res = inStream->Read(inStream, inBuffer, packSize, &processedSize);
64 if (res == SZ_OK && processedSize != packSize)
69 *outBufferSize = unPackSize;
72 *outBuffer = (Byte *)allocMain->Alloc(unPackSize);
74 res = SZE_OUTOFMEMORY;
78 res = SzDecode(db->Database.PackSizes +
79 db->FolderStartPackStreamIndex[folderIndex], folder,
81 inStream, startOffset,
85 *outBuffer, unPackSize, allocTemp);
88 if (folder->UnPackCRCDefined)
90 if (CrcCalc(*outBuffer, unPackSize) != folder->UnPackCRC)
97 allocTemp->Free(inBuffer);
103 CFileItem *fileItem = db->Database.Files + fileIndex;
105 for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
106 *offset += (UInt32)db->Database.Files[i].Size;
107 *outSizeProcessed = (size_t)fileItem->Size;
108 if (*offset + *outSizeProcessed > *outBufferSize)
111 if (fileItem->IsFileCRCDefined)
113 if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)