| OLD | NEW |
| (Empty) |
| 1 /* 7zExtract.c */ | |
| 2 | |
| 3 #include "7zExtract.h" | |
| 4 #include "7zDecode.h" | |
| 5 #include "../../7zCrc.h" | |
| 6 | |
| 7 SZ_RESULT SzExtract( | |
| 8 ISzInStream *inStream, | |
| 9 CArchiveDatabaseEx *db, | |
| 10 UInt32 fileIndex, | |
| 11 UInt32 *blockIndex, | |
| 12 Byte **outBuffer, | |
| 13 size_t *outBufferSize, | |
| 14 size_t *offset, | |
| 15 size_t *outSizeProcessed, | |
| 16 ISzAlloc *allocMain, | |
| 17 ISzAlloc *allocTemp) | |
| 18 { | |
| 19 UInt32 folderIndex = db->FileIndexToFolderIndexMap[fileIndex]; | |
| 20 SZ_RESULT res = SZ_OK; | |
| 21 *offset = 0; | |
| 22 *outSizeProcessed = 0; | |
| 23 if (folderIndex == (UInt32)-1) | |
| 24 { | |
| 25 allocMain->Free(*outBuffer); | |
| 26 *blockIndex = folderIndex; | |
| 27 *outBuffer = 0; | |
| 28 *outBufferSize = 0; | |
| 29 return SZ_OK; | |
| 30 } | |
| 31 | |
| 32 if (*outBuffer == 0 || *blockIndex != folderIndex) | |
| 33 { | |
| 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); | |
| 38 #ifndef _LZMA_IN_CB | |
| 39 Byte *inBuffer = 0; | |
| 40 size_t processedSize; | |
| 41 CFileSize packSizeSpec; | |
| 42 size_t packSize; | |
| 43 RINOK(SzArDbGetFolderFullPackSize(db, folderIndex, &packSizeSpec)); | |
| 44 packSize = (size_t)packSizeSpec; | |
| 45 if (packSize != packSizeSpec) | |
| 46 return SZE_OUTOFMEMORY; | |
| 47 #endif | |
| 48 if (unPackSize != unPackSizeSpec) | |
| 49 return SZE_OUTOFMEMORY; | |
| 50 *blockIndex = folderIndex; | |
| 51 allocMain->Free(*outBuffer); | |
| 52 *outBuffer = 0; | |
| 53 | |
| 54 RINOK(inStream->Seek(inStream, startOffset)); | |
| 55 | |
| 56 #ifndef _LZMA_IN_CB | |
| 57 if (packSize != 0) | |
| 58 { | |
| 59 inBuffer = (Byte *)allocTemp->Alloc(packSize); | |
| 60 if (inBuffer == 0) | |
| 61 return SZE_OUTOFMEMORY; | |
| 62 } | |
| 63 res = inStream->Read(inStream, inBuffer, packSize, &processedSize); | |
| 64 if (res == SZ_OK && processedSize != packSize) | |
| 65 res = SZE_FAIL; | |
| 66 #endif | |
| 67 if (res == SZ_OK) | |
| 68 { | |
| 69 *outBufferSize = unPackSize; | |
| 70 if (unPackSize != 0) | |
| 71 { | |
| 72 *outBuffer = (Byte *)allocMain->Alloc(unPackSize); | |
| 73 if (*outBuffer == 0) | |
| 74 res = SZE_OUTOFMEMORY; | |
| 75 } | |
| 76 if (res == SZ_OK) | |
| 77 { | |
| 78 res = SzDecode(db->Database.PackSizes + | |
| 79 db->FolderStartPackStreamIndex[folderIndex], folder, | |
| 80 #ifdef _LZMA_IN_CB | |
| 81 inStream, startOffset, | |
| 82 #else | |
| 83 inBuffer, | |
| 84 #endif | |
| 85 *outBuffer, unPackSize, allocTemp); | |
| 86 if (res == SZ_OK) | |
| 87 { | |
| 88 if (folder->UnPackCRCDefined) | |
| 89 { | |
| 90 if (CrcCalc(*outBuffer, unPackSize) != folder->UnPackCRC) | |
| 91 res = SZE_CRC_ERROR; | |
| 92 } | |
| 93 } | |
| 94 } | |
| 95 } | |
| 96 #ifndef _LZMA_IN_CB | |
| 97 allocTemp->Free(inBuffer); | |
| 98 #endif | |
| 99 } | |
| 100 if (res == SZ_OK) | |
| 101 { | |
| 102 UInt32 i; | |
| 103 CFileItem *fileItem = db->Database.Files + fileIndex; | |
| 104 *offset = 0; | |
| 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) | |
| 109 return SZE_FAIL; | |
| 110 { | |
| 111 if (fileItem->IsFileCRCDefined) | |
| 112 { | |
| 113 if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCR
C) | |
| 114 res = SZE_CRC_ERROR; | |
| 115 } | |
| 116 } | |
| 117 } | |
| 118 return res; | |
| 119 } | |
| OLD | NEW |