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 |